Reputation: 231
I made a service named UserEvents
@Injectable()
export class UserEvents {
public evAuthenticated: EventEmitter<string> = new EventEmitter();
public AuthUserEvent(email: string) {
this.evAuthenticated.next(email);
}
}
I included this service with the providers in AppModule
I have a service name AuthService that include the UserEvents and emits:
this.userEvents.evAuthenticated.emit(email);
And another service that suscribe
constructor(private userEvents: UserEvents){
this.userEvents.evAuthenticated.subscribe((data: string) => this.SetUser(data));
}
private SetUser(email: string) {
this.logger.info('Event triggered with ' + email);
}
But the suscription is never triggered. At list, SetUser is never called.
What is wrong here?
Upvotes: 2
Views: 6294
Reputation: 231
Thanks for your help, but both are not required in Angular 4. I found the problem: the service that suscribe is not instanciated automatically. I added the service in the constructor of app.component and everything began to work.
Upvotes: 0
Reputation: 34673
Use Subject
instead:
@Injectable()
export class UserEvents {
public evAuthenticated = new Subject<string>();
public AuthUserEvent(email: string) {
this.evAuthenticated.next(email);
}
}
Keep your subscription code as it is.
Check comment from Günter Zöchbauer on my answer here: https://stackoverflow.com/a/45710245/1791913
EventEmitter is not supposed to be used in services. An Observable or Subject does the same. EventEmitter is supposed to be used only for @Output()s. EventEmitter just extends Subject (AFAIR), but the Angular team can change this without prior notice to a custom implementation that still works for @Output() but might break other uses, because @Output() is the only thing EventEmitter is supposed to be used for.
Upvotes: 1
Reputation: 556
From my knowledge of Angular 2(+), EventEmitters are to be used as Component Outputs, i.e.:
@Output() myStringOutput = new EventEmitter<string>();
If you need a triggerable event in your services, it is recommended to use RxJS Subjects, like so:
import { Injectable } from '@angular/core'
import { Subject } from 'rxjs/Subject';
@Injectable()
export class MyService {
private _onMyEvent = new Subject<string>();
public get onMyEvent(): Observable { return this._onMyEvent.asObservable(); }
public trigger(value: string) {
this._onMyEvent.next(value);
}
}
And elsewhere in your code, you can do something like this:
this.myService.onMyEvent.subscribe((value: string) => console.log('Triggered!', value));
this.myService.trigger('Hello World')
Upvotes: 4