Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inject a service manually

Tags:

angular

I have components B, C, D that inherit from class A.

I want to use a service in class A, but I don't know how to inject it, without injecting it from its children.

What I tried is a normal injection:

constructor(pageName: string = null, translate: TranslateService) { 

But when I do super() to construct class A, it throws an error because I didn't supply a second parameter.

Is there a way to inject into a parent class using Angular 2?

The Angular version I am forced to use is: 2.2.1

Some example case: I have many pages, each can show a loader. Instead of injecting the loader every time, and manage the loader from every page, I want to do:

export class BaseComponent {     constructor(private loader: LoadingService) {}          showLoading() {         this.loader.show();     } } 

And then to inherit from the component itself:

@Component({     selector: "page-login",     providers: [UsersService],     templateUrl: "login.html" }) export class LoginPage extends BaseComponent {     constructor(private usersService: UsersService) {         super();     } } 

Now LoginPage has a method showLoading from it's parent.

like image 401
Amit Avatar asked Feb 25 '17 21:02

Amit


People also ask

How can I use service without injecting?

Just use the getter this. aService . They only time this won't work is if you are trying to use AService within the constructor of Bservice , then you would have the same issue of a circular reference since Aservice would not be ready yet. By using the getter you are deferring injecting the service until you need it.

How do you inject service in Angular?

Angular provides the ability for you to inject a service into a component to give that component access to the service. The @Injectable() decorator defines a class as a service in Angular and allows Angular to inject it into a component as a dependency.

What is inject () in Angular?

@Inject() is a manual mechanism for letting Angular know that a parameter must be injected. It can be used like so: import { Component, Inject } from '@angular/core'; import { ChatWidget } from '../components/chat-widget'; ​

Can we use service without dependency injection in Angular?

If no Angular decorator has been used on a class there is no way for Angular to read what dependencies it requires. This is why we need to use @Injectable() . If our service injects providers we must add @Injectable() , which providers no extra functionality, to tell Angular to store that metadata it needs.


1 Answers

You could solve this by using a service locator service. That will easily allow you to get any service and use it in your parent classes without having to inject them via their children (as this can be a pain).

So to use this, create a simple class locator.service.ts:

import {Injector} from "@angular/core";  export class ServiceLocator {     static injector: Injector; } 

Import this service in your app.module.ts:

import {ServiceLocator} from './locator.service'; 

Then in the constructor of your module file (app.module.ts?), init this thing so you can use it anywhere:

export class AppModule {     constructor(private injector: Injector){    // Create global Service Injector.         ServiceLocator.injector = this.injector;     } } 

Now, to use it in your super class (your BaseComponent), simply import the ServiceLocator

import {ServiceLocator} from './locator.service'; 

and use it like:

export class BaseComponent {     public loader;     constructor() {         this.loader = ServiceLocator.injector.get(LoadingService)     }      showLoading() {         this.loader.show();     } } 

Now you have injected your service in an extendable parent and it's usable in your child components without having to pass it in the super().

like image 132
MikeOne Avatar answered Nov 04 '22 05:11

MikeOne