Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2: Inject a non @Injectable class

angular: 2.0.0-beta.9

Is it possible to inject a non @Injectable class into a component ? For example, this class could come from a Third party library.

like image 453
plone1 Avatar asked Mar 17 '16 12:03

plone1


People also ask

What is difference between @inject and @injectable in Angular?

The @Injectable decorator aims to actually set some metadata about which dependencies to inject into the constructor of the associated class. It's a class decorator that doesn't require parameters. Without this decorator no dependency will be injected...

Is @injectable mandatory?

The @Injectable decorator is not compulsory to add if you don't use the 'providedIn' option. The @Injectable decorator together with the 'providedIn' option means the service should not be added within the providers' array of a module.

What does @inject do Angular?

@Inject() is a manual mechanism for letting Angular know that a parameter must be injected. Injecting ChatWidget component to make the component behave like a singleton service so that the component state remain same across the app.

Can we inject component in Angular?

The @Injectable() decorator defines a class as a service in Angular and allows Angular to inject it into a component as a dependency. Likewise, the @Injectable() decorator indicates that a component, class, pipe, or NgModule has a dependency on a service. The injector is the main mechanism.


3 Answers

Yes, it's possible. In fact the @Injectable decorator isn't to specify that a class is injectable into other ones but that you want to inject something in it at the level of its constructor.

If you don't want to inject something in your class, it's not mandatory to add the @Injectable decorator. This class can be injected into other ones.

I think that this Github issue could help you:

  • https://github.com/angular/angular/issues/4404

What is important here is to understand the difference between decorators and annotations. Here is a great article on this subject:

  • http://blog.thoughtram.io/angular/2015/05/03/the-difference-between-annotations-and-decorators.html
like image 154
Thierry Templier Avatar answered Oct 17 '22 11:10

Thierry Templier


I think yes it is possible. I have tested it without @Injectable decorator and it works fine.

plunker

AuthService.ts

 import {Injectable} from 'angular2/core';
 import {Http, Response,HTTP_PROVIDERS} from 'angular2/http';
 import 'rxjs/Rx';
 import {Observable} from 'rxjs/Observable';

 export interface sharedObject{
  firstName:string;
  lastName:stirng;
 }


export class AuthService{
  user:sharedObject;
  constructor()
  {
    console.log('AuthService started')
    this.user={firstName:"micronyks",lastName:"shah"};
  }

  change() {
    console.log('change to angular2');
    this.user.firstName="micronyks1";
    this.user.lastName="shah1";
  }     
}

If you wonder, because some class, use DI in the constructor and do not use @Injectable(). Because this decorated @, for example @Components.

The HeroesComponent has an injected dependency too. Why don't we add @Injectable() to the HeroesComponent?

We can add it if we really want to. It isn't necessary because the HeroesComponent is already decorated with @Component. TypeScript generates metadata for any class with a decorator, and any decorator will do.

For more info you can read this link Angular page

like image 44
Nikhil Shah Avatar answered Oct 17 '22 11:10

Nikhil Shah


If the class has dependencies you still can use it in DI. Just provide a factory for it

If you want to be able to inject a class that itself has dependencies (constructor arguments) but don't want or can't apply @Injectable(), then you can use a factory instead

bootstrap(AppComponent, [
    SomeDep, 
    provide(SomeType, {useFactory: (dep) => new SomeType(dep), 
        deps: [SomeDep]})
]);

You can create variables for such providers to make them easily reusable without this cumbersome declaration (like for example HTTP_PROVIDERS)

export const SOME_TYPE_PROVIDERS: any[] = [
  SomeDep, 
  provide(SomeType, {useFactory: (dep) => new SomeType(dep), 
      deps: [SomeDep]})
];

and then use it like

bootstrap(AppComponent, [SOME_TYPE_PROVIDERS]);
like image 1
Günter Zöchbauer Avatar answered Oct 17 '22 12:10

Günter Zöchbauer