Reputation: 1024
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
Upvotes: 6
Views: 5047
Reputation: 41
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.
Upvotes: 4
Reputation: 7621
I solved it by using @Inject
import { Inject } from "@angular/core;
and i think it should work like this
@Inject(ApiService) api: ApiService;
import { Injectable , Inject } from "@angular/core;
@Injectable()
export class apiService {
public constructor(@Inject(Http) private http: Http) {}
}
import { ReflectiveInjector, Component } from '@angular/core';
import { ApiService } from '../api.service';
@Component({
providers: [ HomeService ]
})
export class Message {
timestamp: number;
message: any;
api: ApiService;
constructor(message: any, @Inject(ApiService) api:ApiService) {
this.timestamp = message.timestamp;
this.message = message.message;
}
}
Upvotes: 2
Reputation: 10578
you can use it while doing bootstrap like this
let nm = new Message(message);
bootstrap(AppComponent, [
APP_ROUTER_PROVIDERS,
[provide(Message,{useValue:nm})],
]).catch(err => console.error(err));
and for this
EXCEPTION: Error: Uncaught (in promise): No provider for Http! (ApiService -> Http)
in service create constructor and import the HTTP like this
import { Http, Response } from '@angular/http';
export class LoginService {
constructor(private http: Http) {
}
}
for this purpose
Oh sorry, this is not how I want to use my class. For every message in the chat I'm making, I instantiate a Message. I don't want just one global Message class but several Message objects.
bootstrap(AppComponent, [
APP_ROUTER_PROVIDERS,
Message //you service here
]).catch(err => console.error(err));
Upvotes: 2