34
votes

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 ?

4
Please add more code to the question. A plunk would also do.Jigar

4 Answers

71
votes

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

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);
        }
      });
  }
}
5
votes

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
0
votes

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