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 refCounting 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);
}