Reputation: 2817
I have this service:
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class MissionService {
// Observable string sources
private missionAnnouncedSource = new Subject<string>();
private missionConfirmedSource = new Subject<string>();
// Observable string streams
missionAnnounced$ = this.missionAnnouncedSource.asObservable();
missionConfirmed$ = this.missionConfirmedSource.asObservable();
// Service message commands
announceMission(mission: string) {
this.missionAnnouncedSource.next(mission);
}
confirmMission(astronaut: string) {
this.missionConfirmedSource.next(astronaut);
}
}
This component:
export class ComponentOne {
constructor(private service: MissionService) { }
onClick() {
console.log('entered in the onclick method');
this.service.announceMission('mission started');
this.service.missionAnnounced$.subscribe(response => console.log('from component 1: ' + response), error => console.log('error: ', error))
}
}
This other component:
export class ComponentTwo {
constructor(private service: MissionService) {
console.log('entered in constructor ComponentTwo')
this.service.missionAnnounced$.subscribe(response => console.log('from component 2: ' + response),
error => console.log('error: ', error));
}
}
I don't know why the console.log
inside subscribe()
with the value of the response on ComponentTwo
is never printed, even the part of the message from component 2:
is never showing up. However the message entered in constructor ComponentTwo
is always showing up.. There is not any error message showing up neither
Upvotes: 0
Views: 459
Reputation: 5379
I had the same problem and the share operator works.
An Observable that upon connection causes the source Observable to emit items to its Observers.
import 'rxjs/add/operator/share';
...
missionAnnounced$ = this.missionAnnouncedSource.asObservable().share();
missionConfirmed$ = this.missionConfirmedSource.asObservable().share();
Upvotes: 0
Reputation: 12879
When using a Subject
, you will only receive notifications of events (values) that are emitted subsequent to you calling subscribe
. In this case, I suspect that the service is emitting its value before the subscription in ComponentTwo
has been created.
If you want the Subject to "remember" its last value, so that new subscribers will see the last value, see for example BehaviorSubject.
Another possibility is that you are providing the service to both components independently, in which case you will actually have two distinct instances of your service. This would mean that events emitted on the service associated with ComponentOne
will not be seen by ComponentTwo
, and vice-versa.
In order for two components to share the same instance of a provider, it should normally be provided in an @NgModule containing them both (and specifically not listed in two places, one for each Component). For example:
@NgModule({
declarations: [ComponentOne, ComponentTwo],
providers: [MissionService], // Will be shared by both components
// ...
})
export class AppModule {
}
Upvotes: 3