Reputation: 1227
export class DataService {
private readonly dataSubject: Subject<Data> = new Subject();
public readonly myData$: Observable<Data>;
constructor() {
this.myData$ = this.dataSubject.asObservable().pipe(
shareReplay({
bufferSize: 1,
refCount: false,
}),
);
// this would solve the problem, but is an ugly workaround
// this.myData$.subscribe();
}
update(data: Data) {
this.dataSubject.next(data);
}
There's this global singleton DataService
, which should provide a certain data to various parts of the application. When the consumers subscribe, they should immediately receive the last value, and the new ones in the future.
My understanding was the following: if I add the shareReplay
as shown above, with refCount
ing turned off, it will subscribe to its upstream observable (ie. the dataSubject
in this case) immediately and keep the last value, and when there are downstream subscribers, emit the last value and also any future ones.
What happens instead, if I understand correctly: if the first downstream subscriber comes later than the first value in source the subject, than the first value is lost, because at that point the shareReplay
was not subscribed to the subject, so it didn't collect the previous value. If I immediately add a downstream subscriber, that fixes the problem, but that's a bit ugly.
I was able to solve my issue with the workaround below which is a bit nicer, where I moved the replay functionality into the subject itself, so that it already keeps the last values regardless of the subscribers. But still would like to know what I might be missing how the shareReplay
works, or if I made a mistake in the code above.
export class DataService {
private readonly dataSubject: Subject<Data> = new ReplaySubject();
public readonly myData$: Observable<Data>;
constructor() {
this.myData$ = this.dataSubject.asObservable().pipe(
share(),
);
}
update(data: Data) {
this.dataSubject.next(data);
}
Upvotes: 2
Views: 4411
Reputation: 28328
When using a Subject
, if the next
happens before a subscribe
, then the value is lost. So new subscribers can't get the last value. Therefore it's recommended to use a ReplaySubject
or a BehaviorSubject
instead to avoid losing values like this.
To answer the actual question, as explained in this article about shareReplay
:
refCount: false means that upon first subscription to ReplaySubject it will subscribe to Source
No, it will not subscribe immediately.
Upvotes: 3