Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inject service in a simple class constructor with Angular2

I created a Message class like this

import { ReflectiveInjector } from '@angular/core';

import { ApiService } from '../api.service';

export class Message {
        timestamp: number;
        message: any;
        api: ApiService;

        constructor(message: any) {
                let injector = ReflectiveInjector.resolveAndCreate([ApiService]);
                this.api = injector.get(ApiService);
                this.timestamp = message.timestamp;
                this.message = message.message;
        }
}

I'm not injecting ApiService directly in the constructor parameters because I'm trying to avoid this: let nm = new Message(message, this.api)
I don't want the service to be in the parameters.

So I'm using the ReflectiveInjector but this code doesn't even work. I get this error : EXCEPTION: Error: Uncaught (in promise): No provider for Http! (ApiService -> Http) even if I include HTTP_PROVIDERS this way

import { bootstrap } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { HTTP_PROVIDERS } from '@angular/http';

import { AppComponent, environment } from './app/';
import { appRouterProviders } from './app/app.routes';

if (environment.production) {
  enableProdMode();
}

bootstrap(AppComponent, [
        appRouterProviders,
        HTTP_PROVIDERS,
])
.catch(err => console.log(err));

How can I use the constructor to instantiate my class and inject my services like this :
let nm = new Message(message);

Thanks

like image 921
Greg Avatar asked Jul 27 '16 18:07

Greg


People also ask

How a service can be injected to a component class?

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.

Can we inject Service inside service in Angular?

You can inject an Angular service in a component, service, directive etc by specifying the service and its type in a component's constructor. Note that injecting a service through a class constructor is, in general, tree-shakable.

How many ways we can inject service in Angular?

There are three types of Dependency Injections in Angular, they are as follows: Constructor injection: Here, it provides the dependencies through a class constructor. Setter injection: The client uses a setter method into which the injector injects the dependency.

What is injectable () Angular?

@Injectable() lets Angular know that a class can be used with the dependency injector. @Injectable() is not strictly required if the class has other Angular decorators on it or does not have any dependencies.


1 Answers

For some reason my answer was deleted without explanation, so here's the answer again:

This is exactly what I have been wondering; What if you really need to call a constructor in your code & still need to inject some things in your class? For example Angular2 tutorial's Hero class is anemic and does not contain any real-world functionality. That's not the case in my application, I need to have a domain objects that contain (a lot of) logic.

Anyway, this is my approach:

@Injectable()
export class MessageFactory {
  constructor(private service: Service)

  build(data: any): Message {
    let message = new Message(data);
    message.service = this.service;
    return message;
  }
}

export class Message {
  service: Service;

  constructor(private data: any) {
    // Can't call service here but it's okay for me...
  }

  doSomethingWithService(): {
    this.service.doSomething(this.data);
  }
}

So somewhere you can inject MessageFactory and create new instances of Messages:

export class MessageExampleComponent {
  constructor(private messageFactory: MessageFactory) {}

  makeMessageDoSomethingWithService(): {
    let message = this.messageFactory.build({just: 'an', example: 'here'})
    message.doSomethingWithService();
  }
}

I'm not sure if calling it MessageFactory is even a correct term, but I would like to have a feedback on this approach before some moderator just deletes this post without comment.

like image 117
Hesse Avatar answered Oct 10 '22 03:10

Hesse