SuperOrange
SuperOrange

Reputation: 713

RxJs get value from observable

In component :

singleEvent$: Observable<Event>;

On init, I get observable

this.singleEvent$ = this._eventService.events$
  .map(function (events) {
    let eventObject = events.find(item => item.id === eventid);
    let eventClass: Event = new Event(eventObject);
    return eventClass;
  });

How can I take current value like event.name ?

Upvotes: 61

Views: 226228

Answers (6)

Dom
Dom

Reputation: 363

If you need the value of an observable at a specific point in time I would convert it to a Promise and await for it like so:

import { firstValueFrom } from 'rxjs';

const value = await firstValueFrom(obs$);

The Observable would resolve immediately if it is an BehaviorSubject under the hood.

Upvotes: 1

Pooria Shahin
Pooria Shahin

Reputation: 59

I hate to say it, but these are all wrong answers. You can easily get the value if it exists by using,

this._eventService.events$.source['_value'] 

And get any value you want from the object. The source is deprecated but still works.

Upvotes: 0

Tlotli Otlotleng
Tlotli Otlotleng

Reputation: 341

Adding to what @ZackDeRose was adding on @Günter Zöchbauer response

private beneficiary = new BehaviorSubject<__IBeneficiary>(newBeneficiary);
beneficiary$ = this.beneficiary.asObservable();

setBeneficiaryInfo(beneficiary: __IBeneficiary): void {
    this.beneficiary.next(beneficiary);
    // when your you subscribe to beneficiary$ you would get the new value
}

/* when implementing in component or other function
   this.beneficiary$.subscribe(
        item => {
            // use current value
        }
    );
*/

modePersonalInformation(personalInfo, mode: string): Observable<any> {
    const $beneficiary = this.beneficiary.value; 
    // this will get the current observable value without the subscrib callback function
    return this.http.post<any>(
        `${this.apiURL}/${mode}-biography/personal` + ((mode === 'update' && $beneficiary?.id) ? `/${$beneficiary.id}` : ''),
        {...personalInfo},
        this.httpOptions
    )
}

you would have to put some conditionals to check if you want to use an existing object or not

Upvotes: 0

Mian Mohsin Younas
Mian Mohsin Younas

Reputation: 101

You can use observable.pipe(take(1)).subscribe to limit the observable to get only one value and stop listening for more.

let firstName: string; 

        this.insureFirstName
            .pipe(take(1))  //this will limit the observable to only one value
            .subscribe((firstName: string) => {
                this.firstName = firstName; asssgning value 
            });
        console.log(this.firstName); //accessing the value

Upvotes: 10

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657068

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}}

Upvotes: 104

ZackDeRose
ZackDeRose

Reputation: 2256

To add on to Günter Zöbauer's answer, a BehaviorSubject may be what you are looking for if you're looking to synchronously get the value inside of your Observable.

A BehaviorSubject is an Observable that always has a value, and you can call myBehaviorSubject.getValue() or myBehaviorSubject.value to synchronously retrieve the value the BehaviorSubject currently holds.

Since it is itself an observable as well, you can still subscribe to the BehaviorSubject to asynchronously react to changes in the value that it holds (e.g. myBehaviorSubject.subscribe(event => { this.event = event })) and use the async pipe in your component's template (e.g. {{ myBehaviorSubject | async }}).

Here's some usage to match your given example to create a BehaviorSubject in your component from the given service:

@Component({
  //...
})
export class YourComponent implements OnInit {
  singleEvent$: BehaviorSubject<Event>;

  constructor(private eventService: EventService){}

  ngOnInit(){
    const eventid = 'id'; // <-- actual id could go here
    this.eventService.events$
      .pipe(
        map(events => {
          let eventObject = events.find(item => item.id === eventid);
          let eventClass: Event = new Event(eventObject);
          return eventClass;
        })
      )
      .subscribe(event => {
        if(!this.singleEvent$){
          this.singleEvent$ = new BehaviorSubject(event);
        } else {
          this.singleEvent$.next(event);
        }
      });
  }
}

Upvotes: 16

Related Questions