Chad Johnson
Chad Johnson

Reputation: 21905

How can I use "resolve" with AngularJS routes to get data for my $scope?

I'd like to use resolve in my AngularJS application's routes to retrieve data from my RESTful API and set it on my $scope.

I've tried the following to no avail -- $scope.forms is not being set:

angular.module('mycompany.resources').factory('Forms', ['$http', function($http) {
    var Forms = {};

    Forms.all = function() {
        return $http.get('/api/forms.json')
    };

    return Forms;
}]);

angular.module('mycompany.admin.forms', ['mycompany.resources']);
angular.module('mycompany.admin.forms').config(['$routeProvider', function($routeProvider) {
    $routeProvider
        .when('/forms', {
            controller: 'formListController',
            templateUrl: 'forms/formList.html',
            resolve: {
                forms: ['Forms', function(Forms) {
                    return Forms.all()
                        .success(function(response) {
                            return response;
                        })
                        .error(function() {
                            return false;
                        });
                }]
            }
        });
}]);

angular.module('mycompany.admin.forms').controller('formListController', ['$scope', 'Forms', function($scope, Forms) {
    'use strict';
}]);

and my template:

<div ng-controller="formListController">
    <ul class="form-list">
        <li ng-repeat="form in forms">
            <a class="form" href="#/forms/{{form._id}}">
                <span class="title">{{form.title}}</span>
                <span ng-if="form.lastPublished">Last published {{form.lastPublished | date:'M/d/yy'}}</span>
            </a>
        </li>
    </ul>
</div>

Upvotes: 1

Views: 5606

Answers (1)

Craig Squire
Craig Squire

Reputation: 2141

I didn't test this out, but the biggest problem seems to be that you're not injecting the value into your controller.

So, just return Forms.all() from your resolve function, since it's already returning a promise. Then inject the value into your controller. Also, consider changing the name to avoid ambiguity.

angular.module('mycompany.resources').factory('Forms', ['$http', function($http) {
    var Forms = {};

    Forms.all = function() {
        return $http.get('/api/forms.json')
    };

    return Forms;
}]);

angular.module('mycompany.admin.forms', ['mycompany.resources']);
angular.module('mycompany.admin.forms').config(['$routeProvider', function($routeProvider) {
    $routeProvider
        .when('/forms', {
            controller: 'formListController',
            templateUrl: 'forms/formList.html',
            resolve: {
                forms: ['Forms', function(Forms) {
                    return Forms.all();;
                }]
            }
        });
}]);

angular.module('mycompany.admin.forms').controller('formListController', ['$scope', 'Forms', 'forms', function($scope, Forms, forms) {
    'use strict';
    $scope.forms = forms;
}]);

From the Angular documentation (http://docs.angularjs.org/api/ngRoute/provider/$routeProvider):

resolve - {Object.<string, function>=} - An optional map of dependencies which should be injected into the controller. If any of these dependencies are promises, the router will wait for them all to be resolved or one to be rejected before the controller is instantiated. If all the promises are resolved successfully, the values of the resolved promises are injected and $routeChangeSuccess event is fired. If any of the promises are rejected the $routeChangeError event is fired. The map object is:

  • key{string}: a name of a dependency to be injected into the controller.

  • factory - {string|function}: If string then it is an alias for a service. Otherwise if function, then it is injected and the return value is treated as the dependency. If the result is a promise, it is resolved before its value is injected into the controller. Be aware that ngRoute.$routeParams will still refer to the previous route within these resolve functions. Use $route.current.params to access the new route parameters, instead.

Upvotes: 3

Related Questions