How to implement infinite scrolling with Node.js, Angular.js and Firebase?

UPDATE 8:

CODE:

<% include ../partials/header %> <script src="https://www.gstatic.com/firebasejs/3.5.2/firebase.js"></script> <script src="https://cdn.firebase.com/libs/firebase-util/0.2.5/firebase-util.min.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.js"></script> <script src="https://cdn.firebase.com/libs/angularfire/1.1.4/angularfire.min.js"></script> <script> var config = { info }; firebase.initializeApp(config); var fb = firebase.database().ref("posts/fun"); var app = angular.module('app', ['firebase']); app.controller('ctrl', function ($scope, $firebaseArray, $timeout) { $scope.data = []; var _start = 0; var _end = 4; var _n = 5; $scope.getDataset = function() { fb.orderByChild('id').startAt(_start).endAt(_end).limitToLast(_n).on("child_added", function(dataSnapshot) { $scope.data.push(dataSnapshot.val()); console.log("THE VALUE:"+$scope.data); }); _start = _start + _n; _end = _end + _n; }; $scope.getDataset() }); // Compile the whole <body> with the angular module named "app" angular.bootstrap(document.body, ['app']); </script> <div class ="containerMarginsIndex"> <div ng-controller="ctrl"> <div class="fun" ng-repeat="d in data"> <h3 class="text-left">{{d.title}}</h3> <div class = "postImgIndex"> <a href="details/{{d.id}}" target="_blank"> <img class= "imgIndex" ng-src="/images/uploads/{{d.image}}" > </a> </div> <div class="postScore">{{d.upvotes - d.downvotes}} HP</div> </div> </div> </div> <% include ../partials/footer %> 

SITUATION:

Ok, I redesigned my Firebase database architecture and changed the Firebase rules.

Now I am sure that the Firebase function returns a value (it registers in the console).

But I still get the following error:

This HTML:

  <div class="fun" ng-repeat="d in data"> <h3 class="text-left">{{d.title}}</h3> <div class = "postImgIndex"> <a href="details/{{d.id}}" target="_blank"> <img class= "imgIndex" ng-src="/images/uploads/{{d.image}}" > </a> </div> <div class="postScore">{{d.upvotes - d.downvotes}} HP</div> </div> 

REPLACED using this RENDERED parameter:

 <!-- ngRepeat: d in data --> == $0 

What I did wrong?

+6
source share
3 answers

It does not appear in your view because you have nothing in $scope and you are not using {{}} to interpolate your data. See the following changes:

Assign data to the $scope variable to be used in the view:

 $scope.data = []; var _start = 0; var _end = 4; var _n = 5; var getDataset = function() { fb.orderByChild('time').startAt(_start).endAt(_end).limitToLast(_n).on("child_added", function(dataSnapshot) { $scope.data.push(dataSnapshot.val()); }); _start = _start + _n; _end = _end + _n; 

And your view, use ngRepeat and {{}} to interpolate:

 <div class ="containerMarginsIndex"> <div class="fun" ng-repeat="d in data"> <h3 class="text-left">{{d.title}}</h3> <div class = "postImgIndex"> <a href="details/{{post.id}}" target="_blank"> <img class= "imgIndex" src="/images/uploads/{{post.image}}" > </a> </div> <div class="postScore">({{d.upvotes - d.downvotes}}) HP</div> </div> </div> 
+3
source

You need to include $scope.$apply() because the scroll event is executed outside the Angular context.

Also, the event listener must be inside your controller so that the available more function is available.

Here's the updated fiddle:

https://jsfiddle.net/xue8odfc/2/

I would say that the problem with Angular that does not resolve {{post.image}} , etc., is due to incompatibility between the libraries you are referencing. I suggest testing using versions from a working jsfiddle:

 <script src="https://cdn.firebase.com/js/client/2.0.3/firebase.js"></script> <script src="https://cdn.firebase.com/libs/firebase-util/0.2.5/firebase-util.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.1/angular.min.js"></script> <script src="https://cdn.firebase.com/libs/angularfire/1.1.4/angularfire.min.js"></script> 
+1
source

Add your scroll listener to your controller. The more function does not really exist, however you have the $scope.more method.

 app.controller('ctrl', function ($scope, $firebaseArray, $timeout) { // ORDERED BY TIME: var ref = firebase.database().ref("posts/fun"); var scrollRef = new Firebase.util.Scroll(ref, "time"); $scope.posts = $firebaseArray(scrollRef); scrollRef.scroll.next(5); // AS DATA APPEARS IN DATABASE ORDERED BY TIME: ref.once('value', function(snap) { $scope.rawdata = snap.val(); $scope.$apply(); }); $scope.more = function() { scrollRef.scroll.next(5); }; // Add scroll listener window.addEventListener('scroll', function() { if (window.scrollY === document.body.scrollHeight - window.innerHeight) { $scope.$apply($scope.more); } }); }); 

Note that I call $scope.more inside $scope.$apply so that the processing area is digested at the end of the call. Indeed, the JS listener in the window scroll event is outside the Angular life cycle, so we need to manually $digest area for Angular to update all its observers and update the HTML. Search the Internet about $scope.$apply if you want to know more about it.

About your first problem

Your Angular application does not start because Angular is never initialized. To do this, you either need to download it synchronously, or use the ng-app directive, or if you do not want to change anything using your code, you can simply add these lines after defining your module and controller:

 // Compile the whole <body> with the angular module named "app" angular.bootstrap(document.body, ['app']); 
+1
source

Source: https://habr.com/ru/post/1012263/


All Articles