How to Get Current Value of Rxjs Subject or Observable

How to get current value of RxJS Subject or Observable?

A Subject or Observable doesn't have a current value. When a value is emitted, it is passed to subscribers and the Observable is done with it.

If you want to have a current value, use BehaviorSubject which is designed for exactly that purpose. BehaviorSubject keeps the last emitted value and emits it immediately to new subscribers.

It also has a method getValue() to get the current value.

Simple way to get current value of an Observable (Obtained from a BehaviorSubject)

As far as I can understand your problem I would propably question the usage of a BehaviourSubject in the first place.
RxJs, as great as it is, is not a fit for every use case and yours could be one of them.
The usage of .value is an indication for that imo.

Using a simple non Observable variable in the SoundMeterService that keeps the state would propably resolve all your problems.

If you don't want to do that, my suggestions would be to try something like the following:
There a several places in your flow where you want to check the listeningStatus and
it may is an option for you to use the tap operator and perform the side effects for all options (not only for 'noResults') in one place?

Example:

export class SoundMeterComponent {
serviceListeningStatus$ = this.sms.listeningStatus.pipe(
tap((status) => {
if (value === 'noResults') {
displayNoResultsMessage();
}
if (value === 'xxx') {
doXXXStuff();
}
})
);

constructor(private sms: SoundMeterService) {}

ngOnInit() {}
}

and the template then subscribes to the serviceListeningStatus$:

<div *ngIf="(serviceListeningStatus$ | async) === 'noResults' ">
<span>some text</span>
</div>

I think your problem is a great example for an application that wants to do RxJs, because it is great, but due the lack of a full support of reactive approaches in the Angular Framework you can't go fully reactive. I'm thinking of the ngOnInit or of click events a user makes.
If you want to use RxJs nonetheless it may help to take look at ngx-template-stream or at this great proposal.

Cheers Chris

Get current value from Observable without subscribing (just want value one time)

You need to use BehaviorSubject,

  • BehaviorSubject is similar to ReplaySubject except it only remembers the last publication.
  • BehaviorSubject also requires you to provide it a default value of T. This means that all subscribers will receive a value immediately
    (unless it is already completed).

It will give you the most recent value published by the Observable.

BehaviorSubject provides a getter property named value to get the most recent value passed through it.


StackBlitz

  • In this example the value 'a' is written to the console:

//Declare a Subject, you'll need to provide a default value.
const subject: BehaviorSubject<string> = new BehaviorSubject("a");

USAGE:

console.log(subject.value); // will print the current value

Conceal the Subject and only expose it's value

In case you want to conceal your BehaviorSubject and only expose it's value, let's say from a Service, you can use a getter like this.

export class YourService {
private subject = new BehaviorSubject('random');

public get subjectValue() {
return this.subject.value;
}
}

Get current value of Subject.asObservable() inside Angular service

Seems you are looking for BehaviorSubject

private _panelOpened = new BehaviorSubject<boolean>(false);

If you subscribe you get the last value as first event.

togglePanel() {
this.currentValue = !this.currentValue;
this._panelOpened.next(this.currentValue);
}

RxJs get value from observable

To get data from an observable, you need to subscribe:

this.singleEvents$.subscribe(event => this.event = event);

In the template you can directly bind to observables using the async pipe:

{{singleEvents$ | async}}

How to get value from Observable

You need to subscribe to the items$ Observable to get the data.

jobsLength() {
this.searchLogic.items$.subscribe((value: any[]) => {
let jobs: any[] = value;
console.log(jobs);
console.log(jobs.length);
});
}

Sample Solution on StackBlitz



References

Observable (Subscribing)

take(1) vs firstValueFrom vs observable.value

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$.pipe(
take(1)
));

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



Related Topics



Leave a reply



Submit