1

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?

2 Answers 2

1

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(...)

Sign up to request clarification or add additional context in comments.

5 Comments

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?
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?
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 ;)
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?
Yes to inject it via factory() inside of the App module
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.