2
votes

I create Observable using 'of' operator and the stream consists of object with array of objects. I subscribe to it and then I push something to this array of objects.

Next I subscribe again to the Observable and I expect the same values as during first subscription, but I get array of objects that has the previous push value. Why is that?

There is some code:

ngOnInit() {
   this.observable = of(
{
  name: "Mark",
  pets: [{
    type: "dog",
    age: 3
  },
  {
    type: "cat",
    age: 2
  }]
});
this.getObservable();
this.getObservableOneMoreTime();
}

getObservable() {
      this.observable.subscribe(r => {
      this.state = r
      this.state.pets.push({type: "bird", age: 1});
    })
}

getObservableOneMoreTime() {
    setTimeout(() => {
      this.observable.subscribe(r => {
      console.log(r);
    })
}, 5000)
  }

In console I'm getting an array with 3 elements (it's including "bird"), but I expect to get initial array - only "dog" and "cat" inside it. I don't understand why this is working in this way. Is there some caching or something like that?

I thought that Observables are Cold in default and every new subscription is returning the starting values to new subscriber.

2

2 Answers

2
votes

The "real" question here is why is the instance passed in to of not reinstatiated when the resulting observable emits to another subscriber. The answer is that of is a function that is called and you pass it an instance.

of(someInstance) // ← executes once

so the passed in instance is also only created 1x when you call of. Now the resulting Observable instance will emit the instance of the object you passed in to of. Calling subscribe multiple times on this observable will not trigger of to be called again to create a new observable. Instead that same instance passed to the observable will be emitted from it.

So again:

  • of(someInstance) // ← executes once to create the Observable
  • result assigned to your field observable (is of type Observable)
  • subscribing to the field observable will always emit the same instance initially passed to of
1
votes

This is because you are modifying the elements of the array and the reference is shared. Both subscribes get a reference to the same object. getObservableOneMoreTime gets its reference after getObservable so by the time it runs the reference to pets has been updated with the new element.