4

Basically I have a timeline with posts that is a $firebaseArray and any change to this array is getting binded properly. But when I want to bind any other data it only binds when ngInfiniteScroll is trying to retrieve more data from firebase, so only when I scroll down.

In the code bellow I'm calling {{getMoreDetails()}} and this data is binded when the first set of data is being retrieved with ngInfiniteScroll but as soon as it is loaded the bind breaks and only binds again when scrolling.

My concerns here are:

  • Was ngInfiniteScroll designed to work this way?
  • Is there any workaround in this scenario?

Stack:

"firebase": "2.4.2","angularfire": "~1.2.0","firebase-util": "0.2.5","ngInfiniteScroll": "1.2.2"

timeline.html

<div ng-controller="TimelineController">
    <section class="entrys main-content" infinite-scroll="posts.scroll.next(3)" infinite-scroll-distance="0.3">
        <div class="inner">
            <div ng-repeat="post in filteredPostsResults = (posts | filter:postIdFilter)">
                <article class="entry">

                    <img ng-if="post.sourceType=='IMAGE'" data-ng-src="{{getPostData(post)}}"/>

                    <div class="entry-info">
                        <h3><div ng-bind-html="post.description | emoticons"></div></h3>
                        <small>posted on <time>{{getDateInFormat(post.createdAt)}}</time></small>
                        {{getMoreDetails()}}
                    </div>

                </article>
            </div>
        </div>
    </section>
</div>

timeline.js

(function (angular) {
      "use strict";

        var timeline = angular.module('myApp.user.timeline', ['firebase', 'firebase.utils', 'firebase.auth', 'ngRoute', 'myApp.user.timelineService']);

        timeline.controller('TimelineController', [ '$scope', '$routeParams', 'TimelineService', '$publisherServices', '$securityProperties', function ($scope, $routeParams, TimelineService, $publisherServices, $securityProperties) {

            if (!$scope.posts){
                $scope.posts = TimelineService.getPosts($routeParams.userId);
            }
            $scope.posts.$loaded(function(result) {
                $scope.isPostsLoaded = true;
            });


            $scope.getMoreDetails = function() {
                console.log("LOGGED ONLY WHEN SCROLLING");
                return $publisherServices.getDetails();
            };

            $scope.getPostData = function(post) {
                if (!post.dataUrl){
                    post.dataUrl = $publisherServices.getAwsFileUrl(post.fileName);
                }
                return post.dataUrl;
            };

            $scope.postIdFilter = function(post) {
                if ($routeParams.postId){
                    if (post.$id == $routeParams.postId) return post;
                } else { return post; }
            };

            $scope.getDateInFormat = function(timestamp){
                var date = new Date();
                date.setTime(timestamp);
                return date;
            };

        }]);

    })(angular);

timelineService.js

 (function (angular) {
      "use strict";

    var timelineService = angular.module('myApp.user.timelineService', []);

    timelineService.service('TimelineService', ['$routeParams', 'FBURL', '$firebaseArray', function ($routeParams, FBURL, $firebaseArray) {
        var posts;
        var currentUserIdPosts;
        var postsRef;

        var self = {
          getPosts: function(userId){
            if (!posts || userId != currentUserIdPosts){
              currentUserIdPosts = userId;
              postsRef = new Firebase(FBURL).child("posts").child(userId);
              var scrollRef = new Firebase.util.Scroll(postsRef, "createdAtDesc");
              posts = $firebaseArray(scrollRef);
              posts.scroll = scrollRef.scroll;
            }
            return posts;
          }

        }
        return self;
      }]);

    })(angular);
adolfosrs
  • 8,626
  • 5
  • 36
  • 65
  • Do your bindings work on init and aren't updated until you scroll down? Or they don't work at all? – buggy1985 Jun 03 '16 at 12:53
  • On what kind of events would you expect the post details to get updated? It seems that your app isn't performing any digest cycle until you scroll down. – buggy1985 Jun 03 '16 at 13:00
  • @buggy1985 Thanks for replying. My binding works on init and as soon as the initial data from firebase is retrieved with ngInifiniteScroll it only binds again when scrolling and attemp to retrieve more data. The `getMoreDetails()` isnt comming from the firebasearray. it is getting another data from another service. The point is that it isnt being called at all. the `console.log` that I'm trying to call isnt logging. – adolfosrs Jun 03 '16 at 13:22

1 Answers1

3

I am assuming that you want the post details updated when the data from your Firebase changes.

When Firebase changes are applied to your scope, it seems that it doesn't trigger a digest cycle, so you probably need to do it manually every time you get updates from Firebase.

Take a look at $$updated in $firebaseArray.$extend (see docs).

// now let's create a synchronized array factory that uses our Widget
app.factory("WidgetFactory", function($firebaseArray, Widget) {
  return $firebaseArray.$extend({

    // override the update behavior to call Widget.update()
    $$updated: function(snap) {
      // we need to return true/false here or $watch listeners will not get triggered
      // luckily, our Widget.prototype.update() method already returns a boolean if
      // anything has changed
      return this.$getRecord(snap.key()).update(snap);
    }
  });
});

I hope this helps.

buggy1985
  • 844
  • 7
  • 20