Lorraine Ram-El
Lorraine Ram-El

Reputation: 2745

take(1) vs firstValueFrom vs observable.value

In my project, I use BehaviorSubjects 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

Answers (1)

martin
martin

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

Related Questions