Firebase coverage is not reflected in Angular view

I am pulling one value from each object in Firebase, picUrl (image url) and storing it in a scope array variable, $ scope.bricks. How can I make it so that the $ scope.bricks variables every time Firebase is updated with a new object, and therefore a new picUrl? Thanks in advance!

angular.module('noorApp').controller('MainCtrl', function ($scope, $http, $firebase) {
    var sync = $firebase(ref);
    var firebaseObj = sync.$asObject();
    $scope.bricks = [];

    firebaseObj.$loaded().then(function(){
        angular.forEach(firebaseObj.products, function(value, key){
            $scope.bricks.push({src: value.picUrl});
        });
    });
});

      

EDIT:

I had to post how I use $ scope.bricks in the DOM.

<div class="masonry-brick" ng-repeat="brick in bricks">
  <img ng-src="{{ brick.src }}">
</div>

      

The problem is that when firebaseObj syncs with Firebase, $ loaded () only works once.
Thank you.

+3


source to share


2 answers


As I said in my comment, you can make it work:

    firebaseObj.$loaded().then(function(){
        angular.forEach(firebaseObj.products, function(value, key){
            $scope.bricks.push({src: value.picUrl});
            $scopy.$apply();
        });
    });

      

Update: the above doesn't work, see OP's comment below.

Read more about $scope.$apply

this article: http://jimhoskins.com/2012/12/17/angularjs-and-apply.html



But even if it might fix your current problem, you will run into other problems later. The reason for this is that you are creating an "unmanaged array" of bricks. AngularFire has quite some code to ensure that Firebase Order Collections and AngularJS Bidirectional Arrays go well together.

For this reason, it's probably best to set up a separate sync for your product array:

angular.module('noorApp').controller('MainCtrl', function ($scope, $http, $firebase) {
    var sync = $firebase(ref);
    var firebaseObj = sync.$asObject();
    $scope.bricks = $firebase(ref.child('products')).$asArray();    
});

      

With this setup AngularFire will automatically call $apply()

when the array elements are loaded or subsequently changed.

+4


source


After reading Frank's answer I realized that my problem was with my html. I was trying to create a new variable from my synchronized variable when I didn't need it. I can just reference the synchronized variable directly.

I had to change my ng-repeat variable, not my model. firebaseObj syncs with Firebase, so let's put it in $ scope.

angular.module('noorApp').controller('MainCtrl', function ($scope, $http, $firebase) {
    var sync = $firebase(ref);
    $scope.firebaseObj = sync.$asObject();
});

      

Now, in the DOM, I have to just specify firebaseObj:

<div class="masonry-brick" ng-repeat="brick in firebaseObj.products">
   <img ng-src="{{ brick.picUrl }}">
</div>

      

Or, as Frank said, we can just pull the products document from Firebase:



angular.module('noorApp').controller('MainCtrl', function ($scope, $http, $firebase) {
    $scope.bricks = $firebase(ref).products.$asArray();
});

      

In this case, the html will look like this:

<div class="masonry-brick" ng-repeat="brick in bricks">
  <img ng-src="{{ brick.picUrl }}">
</div>

      

The point is, by directly referencing the synchronized variable, I don't need to run $ load ()!

Thanks Frank.

+2


source







All Articles