13

I am having a heck of a time trying to figure out why I'm getting the Unknown provider error in Angular. I've checked every other question I could find on the subject and most suggest an error in dependency injection. However, it doesn't seem to me like I'm forgetting to inject anything. I've been trying to get the resolve property to work like this post by Misko. I'm able to console log out the employee data after it's resolved, but then I get the Unknown provider error, which prevents the data from being shown on the page.

Here is my router:

    "use strict";

    var app = angular.module('app',[
      'employeeServices'
    ]);

    app.config(appRouter);

    function appRouter ($routeProvider) {
      $routeProvider
        .when('/employees/:account_id', {
          controller: 'EmployeeCtrl',
          templateUrl: 'view/employee/view.html',
          resolve: employeeCtrl.resolve
        })

        .otherwise({ redirectTo: '/' });
    }

Here is my controller

    var employeeCtrl = app.controller('EmployeeCtrl', [
      '$scope',
      'employees',
      function ($scope, employees) {
        $scope.employee = employees;
        console.log($scope.employee);
      }
    ]);

    employeeCtrl.resolve = {
      employees: function (Employee, $q, $route) {
        var deferred = $q.defer();
        console.log("current params: ", $route.current.params.account_id);
        Employee.getOne({ id: $route.current.params.account_id }, function (successData) {
          deferred.resolve(successData);
        }, function (errorData) {
          deferred.reject(errorData);
        });
        return deferred.promise;
      }
    };

And my factory:

    angular.module('employeeServices', ['ngResource'])
      .factory('Employee', ['$resource', function ($resource) {
        return $resource('/employees/:id/json',
          {
            id: '@account_id'
          },
          {
            'save': {
              method: 'POST',
              isArray: false
            },
            'update': {
              method: 'PUT',
              params: {
                id: '@account_id'
              }
            },
            'remove': {
              method: 'DELETE',
              params: {
                id: '@account_id'
              }
            },
            'getOne': {
              method: 'GET',
              params: {
                id: '@account_id'
              },
              isArray: false
            },
            'query': {
              method: 'GET',
              params: {
                id: '@account_id'
              },
              isArray: true
            }
          }
        );
      }]);

Any suggestions would be so greatly appreciated!

Community
  • 1
  • 1
boardlemur
  • 2,861
  • 1
  • 18
  • 24

2 Answers2

47

So the problem was that I was setting up the EmployeeCtrl controller through ng-controller inside my partial's view, like so:

    <div class="viewPage" ng-controller="EmployeeCtrl">

When using resolve, however, the controller set up must be done through the router in order for it to be available at runtime. I removed the ng-controller="EmployeeCtrl...

    <div class="viewPage">

... and presto, like nothing ever happened.

I have to note that I received help from the kind, patient folks over on the AngularJS IRC channel...

boardlemur
  • 2,861
  • 1
  • 18
  • 24
  • 1
    Cause i set controller with the ngController directive and in the routes i get the unknown provider error message. I forgott to delete the ngController out of the html code. Thanks, syou saved my day – tschiela Dec 10 '13 at 14:21
  • you are absolutely genius and life saver! – unruledboy Oct 27 '15 at 04:16
  • 2016, and this is still great. I've spent over an hour. Ooooh no! Thank you so much! – KhoPhi Jun 11 '16 at 22:42
0

Since you defined the factory called Employee, you should use the exact name to refer to this module when you inject it to the controller.

var employeeCtrl = app.controller('EmployeeCtrl', [
      '$scope',
      'employees',

Change to

var employeeCtrl = app.controller('EmployeeCtrl', [
      '$scope',
      'Employee',
zs2020
  • 53,766
  • 29
  • 154
  • 219
  • I thought that was the issue too at first, but it seems that the `Employee` factory is being injected into an `employees` function defined in a `resolve` object in the controller. Does that make any sense? – Michael Benford Aug 17 '13 at 04:57
  • @MichaelBenford the 2nd `employees` in the original code is the local variable, you can rename it to anything as long as it matches the module in order. The local variables doesn't matter, you can do `app.controller('EmployeeCtrl', ['$scope', 'Employee', function(s, e)`, and `e` will be the `Employee` module injected. But the module name `Employee` is whatever defined in the factory, and it has to be used exactly as what is defined. – zs2020 Aug 17 '13 at 04:59
  • I wasn't talking about the `employees` argument, really. I was talking about this: `employeeCtrl.resolve = { employees: function (Employee, $q, $route)...`. What's `resolve`? Why is it apparently defined directly in the controller? I've never seen a code like that before. – Michael Benford Aug 17 '13 at 05:10
  • @MichaelBenford That `resolve` is lazy initialization of the part of controller and I think it is not incorrect in syntax. `Employee` is nothing but a local variable. – zs2020 Aug 17 '13 at 05:30
  • @MichaelBenford I've picked up that syntax from [this answer](http://stackoverflow.com/a/11972028/1306982) and from John Lindquist's tutorials. The resolve function is working, as I can log out the returned data. It does seem to be an issue with the 'employees' argument, though, as it is saying that that is an unknown provider. The Employee module itself is being injected in this line of the resolve function: `employees: function (Employee, $q, $route)` and that employees function is what is being passed to the EmployeeCtrl in 'employees'. Does that make sense? – boardlemur Aug 17 '13 at 15:21