Darwin Tech
Darwin Tech

Reputation: 18919

Angular router resolve results in an unknown provider error

I am trying to use Angular's routing to resolve the necessary objects for the controller scope. I have read a few tutorials on how to do this but I still get an Unknown Provider error. The issue seems to be with project being injected into ProjectDetailCtrl.

app.js

var myApp = angular.module('myApp', ['ngRoute']);

myApp.config( function ($interpolateProvider, $routeProvider) {
    $routeProvider
    ...
    .when('/project/:projectId', {
        templateUrl : 'partials/_project_detail.html',
        controller: 'ProjectDetailCtrl',
        resolve: {
            project: function ($route, MyService) {
                return MyService.get('projects/', $route.current.params.projectId).then(function(data) {
                    console.log('VERIFY DATA: ', data);
                    return data;
                });
            }
        }

controllers.js

.controller('ProjectDetailCtrl', function ($scope, project) {
    $scope.project = project;
}

Edit

services.js

.factory('MyService', function ($http, $q) {

var MyService = {
    ...
    get: function (items_url, objId) {
        var defer = $q.defer();
        $http({method: 'GET', 
            url: api_url + items_url + objId}).
            success(function (data, status, headers, config) {
                defer.resolve(data);
            }).error(function (data, status, headers, config) {
                defer.reject(status);
            });
        return defer.promise;
    },

Edit 2

The issue is apparently not with the Service method, as this also produces the error:

app.js

var myApp = angular.module('myApp', ['ngRoute']);

myApp.config( function ($interpolateProvider, $routeProvider) {
    $routeProvider
    ...
    .when('/project/:projectId', {
        templateUrl : 'partials/_project_detail.html',
        controller: 'ProjectDetailCtrl',
        resolve: {
            project: {title: 'foo'}
        }
     });
})

I can verify my resolve function is being returned properly, but Angular still complains that project is unidentified. What is this issue here? I have tried making my controllers into a module and passing that to the myApp module, but I still get the same Unidentified Provider issue for project.

Note: I am using Angular 1.2.9.

Edit 3: solution

So the issue was this line in my template:

<!-- WRONG: <div ng-controller="ProjectDetailCtrl">-->
<div>

  <h2 ng-show="project">Project: <strong>{{ project.title }}</strong></h2>

</div>

Apparently the ng-controller directive cannot be use with resolve.

Upvotes: 5

Views: 7364

Answers (3)

DDM
DDM

Reputation: 1129

This question has been asked before, therefore it's a possible duplicate.

  • The top answer points out usage of controllers within markup to have caused this.
  • Search your codebase (markup or templates to be exact) for the term ng-controller.
  • Verify if there is a matching controller, as in this case ProjectDetailCtrl
  • Remove it from the markup

It solved the problem in my case.

Upvotes: 0

user2445933
user2445933

Reputation:

You forgot to add ngRoute as a dependency for your module. Thats why $routeProvider and $route service are undefined.

Update:

See this example. Problem was in ng-controller directive

Upvotes: 2

Jonathan Rowny
Jonathan Rowny

Reputation: 7588

You're returning the MyService.get, which is a promise, and then within the result of the promise, you're returning the data.... but to what?

You want to return the promise, but not the original promise... so you create your own promise using $q, and Angular will wait and resolve it for you before loading your route.

project: function ($route, MyService) {
            var deferred = $q.defer();
            MyService.get('projects/', $route.current.params.projectId).then(function(data) {
                console.log('VERIFY DATA: ', data);
                deferred.resolve(data);
            });
            return deferred.promise;
        }

Or, assuming MyService.get returns a promise, you should be able to just do

 project: function ($route, MyService) {
            return MyService.get('projects/', $route.current.params.projectId);
        }

And obviously inject $q into config

Upvotes: 0

Related Questions