user2483724 user2483724 - 1 month ago 20
AngularJS Question

Data from firebase not loading on route change, but does on refresh

I'm using angularFire with Angular to update some views but the strange thing is when I switch from view to view the data doesn't load, but when I refresh the page it does. What's going on?

WizardController:

/* initialize data */

var ref = new Firebase('https://dlwj.firebaseio.com/');

/* set data to automatically update on change */

$scope.currentLocation = $route.current.$$route.originalPath;
$scope.propertyRef = $firebase(ref);

$scope.propertyRef.$on('loaded', function(value) {

//value will be undefined when I switch views using hash routes.
//there is no issue when I just refresh on that page.
console.log(value);
$scope.propertyConfiguration = value.products;
var products = [];
for (var key in value.products) {
if (value.products.hasOwnProperty(key)) {
products.push(key);
}
}

$scope.productsArray = products;

});

console.log('Data retrieved');


Routes:

$routeProvider.when('/SharedProperties',
{
templateUrl: 'partials/SharedPropertiesPartial.html',
controller: 'WizardController'
});

$routeProvider.when('/Registration',
{
templateUrl: 'partials/Registration.html',
controller: 'WizardController'
});

$routeProvider.when('/Login',
{
templateUrl: 'partials/Login.html',
controller: 'WizardController'
});

Answer

There is no reason to download the data using a wrapper lib like $firebase (which takes care of synchronization and such) and then immediately pull that data out and put it into a different scope object.

Just declare your scope var:

$scope.products = $firebase(ref);

And to use it:

<ul>
   <li ng-repeat="product in products | orderByPriority">{{product|json}}</li>
</ul>

If you need to iterate the data in a controller or service:

$scope.products = $firebase(ref);

// some time later, probably in $scope.products.$on('loaded')...
// note that $getIndex() is only useful here to get the keys in
// the order they appear in the database, otherwise, forEach($scope.products, ...)
// is sufficient
angular.forEach($scope.products.$getIndex(), function(key) {
   console.log(key, $scope.products[key]);
});

If you want to use Firebase as a static database (which is quite baffling to a lover of all things real-time like myself) and not be notified each time there is a change, you can simply do the following:

angular.controller('MyController', function($timeout, $scope) {
   new Firebase('<URL>').once('value', function(snap) {
      $timeout(function() {
         $scope.products = snap.val();
      });
   });
});

And then utilize it normally:

<ul>
   <li ng-repeat="(key,product) in products">{{key}}: {{product|json}}</li>
</ul>