Sign up ×
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other. Join them; it only takes a minute:

I've been trying to inject factory into a controller using both Angularjs and Typescript, but I'm getting this error Error: [$injector:unpr] http://errors.angularjs.org/1.2.9/$injector/unpr?p0=AuthenticationProvider%20%3C-%20Authentication.

I've been researching around, but can't find a solution because what I did is similar to some of the solution.

Here is my Login controller module

import Authentication = require('AuthenticationService');
module LoginController{

export interface UIMainScope extends ng.IScope {
    login: (credential: any) => void;
}

export class Controller {
    static $inject = ['$scope', '$http', 'Main', 'Authentication'];
    constructor (){}
}
export = LoginController
angular.module('App').controller('Controller', LoginController.Controller);

Did I forget to inject something here to invoke the method?

share|improve this question

2 Answers 2

up vote 1 down vote accepted

The issue here is related to the fact, that the angular's $inject cannot profit from the Typescript require. These are independent features, they represent different concepts.

The angular's [$inject][1], as a built-in Dependency Injection, can only inject, what was already registered. It does not have any access to Typescript objects - just to it's own (angular's) Object Factory.

As the error says: unknown provider 'AuthenticationProvider', we have to call:

angular.module('App')
  .factory('Authentication', [... its dependencies ...
      , (params) => new Authentication(params)]);

Now, we do have Authentication ready in angular, and we can ask for that inside of our Controller

The syntax could look like this:

// module with Scope and Controller
module LoginController
{
  export interface UIMainScope extends ng.IScope 
  {
    login: (credential: any) => void;
  }

  export class Controller
  {
    // constructor, instantiating private members this.$scope ...
    constructor($scope: UIMainScope
       , $http :ng.IHttpService
       , Main: any
       , Authentication: any)
    ...
  }
}

// and finally pass it into angular as .controller()
angular.module('App')
  .controller('Controller', [
     '$scope', '$http', 'Main', 'Authentication',
     ($scope, $http, Main, Authentication)  =>
     {
        return new LoginController.Controller($scope, $http, Main, Authentication);
     }
]);

Finally: in cases, that Authentication provider will not profit from beeing initiated with Angular, we can use it as well. We do NOT have to regiester it at all. Just call require, and access its methods as well... but we have to skip the angular¨s $inject process...

This maybe is not this case, but imagine some QueryStringBuilder... which could consume just a passed params in a method Builder.build(...)

share|improve this answer
    
The error is still there though :( – Test Jul 3 '14 at 18:11
    
That would be related to the fact, that there is missing declaration .factory('Authentication'). If this is in another module (e.g. 'Auth'), do not forget to reference the module in the angular.module('App',[...here reference like, 'Auth']). The finall line in my answer, represents standard angular .controller() definition. The error represent standard situation, when some dependency is missing... Does it help? – Radim Köhler Jul 3 '14 at 18:16
    
Yes it does. Thank you! I thought when I do : static $inject = ['$scope', '$http', 'UIMainUIModelService', 'Authentication']; ==> this is basically inject into the module while the import will import and reference the module? – Test Jul 3 '14 at 18:21
1  
The $inject is the angular world, the import is typescript world. They are totally independent. Different concepts. The $inject can only inject, what was already registered. It does not have any access to imported TS stuff. So, If you will register .factory('Authentication'...) in angular (if we like TS, it would be almost the same way/style as I showed for the controller) - then you can ask $inject to use it... Wish it is now more clear ;) – Radim Köhler Jul 3 '14 at 18:29
    
That explanation makes a lot of sense now. When you say register to Angular, do you mean as in registering in the app itself or the controller module? – Test Jul 3 '14 at 20:05

Seem like you don't have the Authentication service registered with angular specifically:

angular.module('App').controller('Controller', LoginController.Controller)
    // fix based on your code 
    .service('Authentication',Authentication.AuthenticationService); 

This video might help : https://www.youtube.com/watch?v=Yis8m3BdnEM&hd=1

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.