Search code examples
javascriptangularjsngroute

AngularJS Dependency injection in controller of routeProvider resolve


Injecting the return object of a resolve which should be injected into the controller, but it's not. I am using a promise so that the controller does not instanciate until the promise is resolved, since I am doing a HTTP POST using the $http service.

I am also doing some redirection depending on the response data by using $location.path. The first route will redirect to the template1 route with the data it has obtained.

$routeProvider
    .when("/auth/:id", amd.route(
    {   
        controller: 'eventController',
        controllerUrl: 'app/controllers/eventController',
        resolve: {
            returnedData: ['$http', '$location', '$route', '$q', function ($http, $location, $route, $q) {
                var id = $route.current.params.id;
                var defer = $q.defer();
                $http({
                    method: 'POST',
                    url: 'http://domain/service/webapi',
                    data: { 'name': id }
                }).then(function (response) {
                    var template = "/template".concat(response.data.displayLayout);
                    defer.resolve(response.data);
                    $location.path(template);
                    return defer.promise;
                });
            }]
        }
    }))
    .when("/template1", amd.route(
    {
        templateUrl: 'views/templates/template1.html',
        controller: 'eventController',
        controllerUrl: 'app/controllers/eventController',
    }));

app.controller('eventController', ['$scope', '$routeParams', '$timeout', 'returnedData',
    function ($scope, $routeParams, $timeout, returnedData) {
        // ...controller code here: $scope.returnedData = returnedData
});

I am getting the AngularJS error:

Error: $injector:unpr Unknown Provider

Any thoughts on this?


Solution

  • In the AngularJS API page, about the routeProvider (https://docs.angularjs.org/api/ngRoute/provider/$routeProvider)

    you can see:

    resolve - {Object.=} ... 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

    You should edit your code like below:

    var id = $route.current.params.id;
    var defer = $q.defer();
    $http({
        method: 'POST',
        url: 'http://domain/service/webapi',
        data: { 'name': id }
    }).then(function (response) {
        var template = "/template".concat(response.data.displayLayout);
        defer.resolve(response.data);
        $location.path(template);
    });
    // return the promise outside `then` method, then angularjs will wait it `resolve`
    return defer.promise;
    

    And further more, Please notice this:

    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.