I have a general understanding of how Angular2/RXJS observables work when they are subscribed to but I'm making a mistake somewhere.
In my service I have an observable available like so:
// Source
private objectDetailsCache = new Subject<ObectDetails>();
// Stream
public objectDetails$ = this.objectDetailsCache.asObservable().cache();
The service manipulates the observable with these methods:
updateObject(object: ObjectDetails): Observable<ObjectDetails> {
let objectMapped = this.mappingService.mapObjectDetailsToObject(object);
this._HTTPService.update(this._objectUrl + object.id, objectMapped)
.subscribe(o => {
this.objectDetailsCache.next(o);
});
return this.objectDetails$.last();
}
getObjectDetails(id: number): Observable<ObjectDetails> {
this._HTTPService.get(this._objectUrl + id + '/details')
.subscribe(o => {
this.objectDetailsCache.next(o);
})
return this.objectDetails$.last();
}
I have a parent component that subscribes to the observable and tracks the changes made to it by its children
constructor(private objectService: ObjectService) {
objectService.objectDetails$.subscribe(o => this.object = o);
}
Then the component tells the app which object it wants observing:
ngOnInit() {
this.loadObjectDetails();
}
loadObjectDetails() {
this.sub = this.route.params.subscribe(params => {
let id = +params['id'];
this.objectService.getObjectDetails(id)
.subscribe(
o => { },
error => { });
});
}
This so far is all okay. The problem comes when the child components subscribe to the parent's object observable:
ngOnInit() {
this.sub = this.objectService.objectDetails$.subscribe(
o => {
this.object = o;
this.getHeaders()
}
);
}
ngOnDestroy(){
this.sub.unsubscribe();
}
When the parent changes the object it is observing, the child is hit with every object that has been observed previously instead of just the last one. So in this child's case if the parent has observed 3 objects this.getHeaders() is called 3 times when the child subscribes.
I've tried moving the child methods to the complete part of the subscription:
() => this.getHeaders()
but it never gets hit.
I've tried putting the parent subscription in ngOnInit() and unsubscribing in ngDestroy() but it fails to subscribe to anything like that.
Any suggestions about how I can adjust how I go about this would be great.
I hope this makes sense, Thanks in advance.