Current Behavior
BehaviorSubject.getValue() always returns initial value if subscribed to an observable from Webpack library while the observable is emitting new values.
Reproduction
-Minimum code which reproduces bug:
https://github.com/es-repo/bug-repro/tree/master/rxjs/behavior-subject-and-observable-from-lib
Run "npm start" from within the "app" folder or open this link https://es-repo.github.io/bug-repro/rxjs/behavior-subject-and-observable-from-lib/app/dist/. And open console.
Code from the "app" which reproduces the issue:
import { BehaviorSubject, interval } from 'rxjs';
import createObservable from 'lib';
const subject1 = new BehaviorSubject(undefined);
createObservable().subscribe(subject1);
const subject2 = new BehaviorSubject(undefined);
interval(1000).subscribe(subject2);
subject1.subscribe(v => {
console.log(`Observable from lib: value=${v} getValue()=${subject1.getValue()}`);
});
subject2.subscribe(v => {
console.log(`Observable from app: value=${v} getValue()=${subject2.getValue()}`);
});
Code from the "lib":
import { interval } from 'rxjs';
export default function createObservable() {
return interval(1000);
}
Console output:
Observable from lib: value=undefined getValue()=undefined
Observable from app: value=undefined getValue()=undefined
Observable from lib: value=0 getValue()=undefined
Observable from app: value=0 getValue()=0
Observable from lib: value=1 getValue()=undefined
Observable from app: value=1 getValue()=1
...
Expected behavior
BehaviorSubject.getValue() should return last value emitted from Observable.
Environment
Additional context
Related issue: #5051
Hi es-repo. I made a pull request to your reproduction that adds a working example that uses an app local source.
Thanks, samal!
Who use to subscribe with other observable ?
const subject2 = new BehaviorSubject(undefined);
interval(1000).subscribe(subject2);
I don't think this is a correct usage and even i don't know what will happen that way passing observable directly as a subscription.
const subject2 = new BehaviorSubject(undefined);
interval(1000).pipe(mergeMap(() => subject2)).subscribe(console.log)
subject2.next(true)
Who use to subscribe with other observable ?
const subject2 = new BehaviorSubject(undefined);
interval(1000).subscribe(subject2);
@Stradivario sorry, could you elaborate what do you mean?
observable.subscribe(subject) is how you convert unicast observable into multicast. Or, in another way, subject is both an observable and an observer and as an observer it can be subscribed to observable. What's wrong here from your point of you?
Who use to subscribe with other observable ?
const subject2 = new BehaviorSubject(undefined); interval(1000).subscribe(subject2);@Stradivario sorry, could you elaborate what do you mean?
observable.subscribe(subject) is how you convert unicast observable into multicast. Or, in another way, subject is both an observable and an observer and as an observer it can be subscribed to observable. What's wrong here from your point of you?
Never seen such a composition of observables i am really sorry if i miss understood it. I just prefer different approach of composing with pipe. My subscribe method is the last thing that i will write even i try to not write subscribe in my code. That's a different scenario and mind set which doesn't belong to me and i will try to get the best from it.
Regards and Merry Christmas,
Kristiyan Tachev
This is a bug, but it cannot easily be fixed. The problem is that the subject isn't seen as a safe/trusted subscriber because the interop source won't see the per-package Symbol that identifies the subject as trusted.
And that means that the subject will be 'cloned' so that an unsubscribe method can be added to it:
And that means the the subject's original state will remain unchanged - the bug you reported.
Is there any way to work around it —while still transpiling w/ Webpack— without resorting to using another kind of Subject?
@cartant isn't this handled now in the beta version?
@benlesh It's quite likely that https://github.com/ReactiveX/rxjs/pull/5472 fixes it, but that was merged only about 3 weeks ago, so it's probably not in the published beta - I cannot remember the date it was published. I didn't have this issue in mind when I made that fix, but 🤞
Most helpful comment
@benlesh It's quite likely that https://github.com/ReactiveX/rxjs/pull/5472 fixes it, but that was merged only about 3 weeks ago, so it's probably not in the published beta - I cannot remember the date it was published. I didn't have this issue in mind when I made that fix, but 🤞