I'm using Angular 2 and I have noticed an unexpected behaviour.
I have a datasource class, which extends DataSource, with two variables:
private archives = new BehaviorSubject<MyArchive[]>([]);
public archives$: Observable<MyArchive[]> = this.archives.asObservable();
private filteredArchive: MyArchive[];
I update archives this way within the class:
this.archives.next(this.filteredArchive);
Outside in another class I try to subscribe to the observable but it doesn't work:
ngAfterViewInit(): void {
this.dataSource.archives$.subscribe((archive: Array<MyArchive>) => {
console.log(archive.length);
console.log(archive);
console.log(archive.length);
}
}
In the console log it prints:
0
<THE ARCHIVE WITH AN OBJECT INSIDE AS IT SHOULD BE, WITH LENGTH = 1>
0
So that I can't iterate on the archive variable because its length is 0. What's going on here?
the issue this the value is already emitted before you subscribe. Think of observables like tv stream and your data is like a show on this stream if you open the tv after the show ended (subscribe after you pushed the data) you never see the show. if you want your observable to keep the last value you can use the Scan operator like this :
and you can update the Arcjive useing the update method in the datasource class like:
I'm not sure why you're redundantly creating
archives$
andarchives
. You can do it with just a single BehaviorSubject.I think you should be doing this:
And then,
When you use this statement:
a reference to the
archive
object is shown in the console (see the MDN documentation). The content of the object can be different when you inspect it in the console (by clicking on the arrow) from what it was when theconsole.log
statement was executed.In order to see what the actual content is at a specific moment, you should output a string representation of the object:
You can expermiment with this stackblitz to see the various console outputs.
I solved the problem. I forgot that this.filteredArchive is updated by an HTTP GET request. I was trying to push data within this.filteredArchive using forEach, but I forgot to call then() when all the data are received. Hence I was trying to access, using subscribe, a result that was not yet ready.
Thanks everyone for the replies!