Test
Test

Reputation: 87

Inject factory into a controller angularjs + typescript

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?

Upvotes: 1

Views: 3076

Answers (2)

Radim Köhler
Radim Köhler

Reputation: 123891

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

Upvotes: 1

basarat
basarat

Reputation: 276085

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

Upvotes: 0

Related Questions