Reputation: 2745
In my project, I use BehaviorSubject
s as data stores to store the state of my application.
I need only the current value that is currently held in the BehaviorSubject
store, and don't need to subscribe to future values that can be emitted through the behavior subject.
I found few implementations of how to do this: using pipe(take(1))
, firstValueFrom
and .value
.
Do all work the same way and read the current value in the BehaviorSubject store? What are the differences between them, if any?
private myStore$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
// reading only one current value using take(1):
this.myStore$.pipe(take(1))
.subscribe(value => console.log('current value = ', value));
// reading only one current value using firstValueFrom:
const value = await firstValueFrom(this.myStore$);
console.log('current value = ', value);
// reading only one current value using this.myStore$.value:
const value = this.myStore$.value;
console.log('current value = ', value);
Upvotes: 9
Views: 23765
Reputation: 96891
Basically using take(1)
or firstValueFrom
is the same because they access the value asynchronously:
myStore$.pipe(
take(1)
).subscribe(value => {...});
firstValueFrom
turns Observable into a Promise so you can use async
/await
:
const value = await firstValueFrom(myStore$);
Using BehaviorSubject.value
to synchronously access its value is in general not recommended. It might behave unexpectedly if BehaviorSubject
errors or when it's unsubscribed:
import { BehaviorSubject } from 'rxjs';
const subject1 = new BehaviorSubject(1);
console.log(subject1.value);
subject1.error(new Error('broken'));
try {
console.log(subject1.value);
} catch (e) {
console.error(e);
}
const subject2 = new BehaviorSubject(2);
console.log(subject2.value);
subject2.unsubscribe();
try {
console.log(subject2.value);
} catch (e) {
console.error(e);
}
Live demo: https://stackblitz.com/edit/rxjs-npalak?devtoolsheight=60
Upvotes: 15