Dimcho
Dimcho

Reputation: 163

AngularJS - resolve $http instead injecting value

I have a small tool, using AngularJS with the .value() recipe, which currently dumps almost the entire DB as JSON into this value. So I want to optimise the pages by loading some of this information on demand with $http before changing the view.

index.php (ugly)

    <script type="text/javascript" src="js/app.js"></script>
    <script type="text/javascript">
        app.value('MembersListData', <?php echo $MembersListDB; ?>);
        app.value('ChartsData', <?php echo $MembersChartsDB; ?>);
    </script>

app.js

var app = angular.module('CommunityInfo', ['ngRoute', 'chart.js'])
    .config(function ($routeProvider, $httpProvider){
        $routeProvider
            // main page (listing)
            .when('/members', {
                controller: 'MembersController',
                templateUrl: self.location.pathname + '/views/members-list.html'
            })
            // member of the list (load additional data from request.php)
            .when('/member/:memberID', {
                controller: 'MembersController',
                // ----- new code (start) -----
                resolve: {
                    MemberDataDB: function($http, $route){
                        return $http.
                            get(
                                self.location.origin +
                                self.location.pathname +
                                'request.php?rop=info&battleTag=' +
                                $route.current.params.memberID
                            )
                            .then(
                                function(response){
                                    return response.data;
                                }
                            )
                    }
                },
                // ----- new code (end) -----
                templateUrl: self.location.pathname + '/views/member-data.html'
            })
    })


    .factory('MembersFactory', function($http, MembersListData, ChartsData){
        // factory functions & initialization
    })


    .controller('MembersController', 
    function($scope, $routeParams, $location, MembersFactory, MemberDataDB){
        function init(){

            // other initialization

            if (memberID){
                // copy part of the current data
                $scope.memberData = $scope.membersList[memberID];
                if (!$scope.memberData){
                    // member not found - redirect to list
                    $location.path('/members');
                }
                // add the new data
                angular.merge($scope.memberData, MemberDataDB); // new code
            }
        }
        init();
    });

This change is working fine on member page, but loading the list (main page) throws injector error:

Error: [$injector:unpr] http://errors.angularjs.org/1.5.8/$injector/unpr?p0=MemberDataDBProvider%20%3C-%20MemberDataDB%20%3C-%20MembersController

But none of the cases seems to apply here

Am I on the right track? Is there other/better (and beautiful) way to do this?

Upvotes: 0

Views: 105

Answers (1)

nikjohn
nikjohn

Reputation: 21880

The error is being thrown because in the main route, you haven't defined the MemberDataDB resolve variable, although you're sharing the controller between your routes. Therefore, MembersController doesn't know what MemberDataDB is, when it is in the /members route. Try this:

 .when('/members', {
            controller: 'MembersController',
            templateUrl: self.location.pathname + '/views/members-list.html',
            resolve: {
              MemberDataDB: function() {return {}};
            }
        })

Upvotes: 2

Related Questions