Question

I've been experimenting a little with Angular.js lately. As part of this I created a very simple set of controllers with an ng-view and templates to trigger depending on the route requested. I'm using angularFireCollection just to grab an array from Firebase. This works fine in the thumbnailController which does not form part of the ng-view.

My problem is that in addition to the data flowing into the thumbnailController, I also need the two other controllers to be able to access the data. I initially simply set the data to either be part of $rootScope or to have the ng-view as a child of the div in which the thumbnailController is set.

However, the issue from that perspective is that each sub-controller presumably attempts to set the data in the template before it is actually available from Firebase.

The solution appears to be using resolve as per the answer to this question angularFire route resolution. However, using the below code (and also referencing angularFireCollection) I get an error message of angularFire being an unknown provider. My understanding is the code below should be sufficient, and I would also add that the usage of angularFireCollection in thumbnailController works fine as I say.

I also experimented with injecting angularFire/aFCollection directly into the controllers using .$inject however a similar issue arose in terms of it being considered an unknown provider.

If possible could someone advise on what the issue may be here?

var galleryModule = angular.module('galleryModule', ['firebase']);

galleryModule.config(['$routeProvider', 'angularFire', function($routeProvider,  angularFire){
$routeProvider.
    when('/', {
        controller: initialController,
        templateUrl: 'largeimagetemplate.html',
        resolve: {images: angularFire('https://mbg.firebaseio.com/images')}
    }).
    when('/view/:id', {
        controller: mainimageController,
        templateUrl: 'largeimagetemplate.html',
        resolve: {images: angularFire('https://mbg.firebaseio.com/images')}
    }).
    otherwise({
        redirectTo: '/'
});
}]);

galleryModule.controller('thumbnailController', ['$scope', 'angularFireCollection',       function($scope, angularFireCollection){
    var url = 'https://mbg.firebaseio.com/images';
    $scope.images = angularFireCollection(url);
}]);

function initialController($scope,images){
    $scope.largeurl = images[0].largeurl;
}


function mainimageController($scope, images, $routeParams){
  $scope.largeurl = images[$routeParams.id].largeurl;
}
Was it helpful?

Solution

I got the chance to dig into this a little bit - it seems like regular services cannot be used in .config sections. I'd instantiate angularFire in the controller instead of using resolve, for example:

galleryModule
.value("url", "https://mbg.firebaseio.com/images")
.controller('thumbnailController', ['$scope', 'angularFireCollection', 'url',
    function($scope, angularFireCollection, url) {
        $scope.images = angularFireCollection(url);
    }])
.controller('initialController', ['$scope', 'angularFire', 'url',
    function($scope, angularFire, url) {
        angularFire(url, $scope, 'images').then(function() {
            $scope.largeurl = $scope.images[0].largeurl;
        });
    }])
.controller('mainimageController', ['$scope', 'angularFire', '$routeParams', 'url',
    function($scope, angularFire, $routeParams, url){
        angularFire(url, $scope, 'images').then(function() {
            $scope.largeurl = $scope.images[$routeParams.id].largeurl;
        });
    }]);

This is not ineffecient, since the data is only loaded once from the URL by Firebase, and all subsequent promises will be resolved almost immediately with data already at hand.

I would like to see angularFire work with resolve in the $routeProvider, however. You can use this method as a workaround until we figure out a more elegant solution.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top