Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get last emitted Observable

I've created an Angular service that basically sets an object with some user information. When I change the user, the service emits an observable, captured by some sibling components to update the info. The problem is that the first time I set the data, there's no one subscribed yet, so I get an undefined value. I've read about converting the observable to 'hot' using publish() or share() but I'm pretty new to RxJS and I still haven't understood how it works at 100% so I'm a little lost.

The service code (the relevant part):

getFwcUser() : Observable<FwcUser> {
  return this.subjectFwcUser.asObservable();
}

setFwcUser(user : FwcUser) {
  this.fwcUser = user;

  this.subjectFwcUser.next(this.fwcUser);
}

NOTE: FwcUser is an interface with some user fields. I run setFwcUser inside a button handler to choose the user.

The late subscriber (component code):

ngOnInit() {
  this.fwcUserService.getFwcUser()
    .subscribe(
      (user : FwcUser) => { console.log('Received: ', user); this.fwcUser = user; }
  );
  [......]
}

Always prints: 'Received: undefined'. NOTE: The component is inside an '*ngIf="fwcUser"', so it's being loaded when I call to 'setFwcUser' from a sibling component.

How could I get this component to read the last value?

Also, could someone recommend a good resource to learn about RxJS for beginners? I'm reading a couple of books on Angular4 but none of them explain it clearly...

Thanks!

like image 700
Fel Avatar asked Sep 19 '17 14:09

Fel


People also ask

How do you get the last emitted value from Observable?

Rather than a standard subject (Observable) that just emits values as they come in, a BehaviorSubject emits the last value upon subscribe() . You can also get the last value manually using the BehaviorSubjects getValue() method.

How do I get the last value from BehaviorSubject?

The BehaviorSubject There are two ways to get this last emited value. You can either get the value by accessing the . value property on the BehaviorSubject or you can subscribe to it. If you subscribe to it, the BehaviorSubject will directly emit the current value to the subscriber.

How can I get RXJS value?

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.

What is takeUntil in RXJS?

What is TakeUntil. The takeUntil operator is used to automatically unsubscribe from an observable. takeUntil begins mirroring the source Observable. It also monitors a second Observable, notifier that you provide. If the notifier emits a value, the output Observable stops mirroring the source Observable and completes.


1 Answers

BehaviorSubject is the answer here. Rather than a standard subject (Observable) that just emits values as they come in, a BehaviorSubject emits the last value upon subscribe(). You can also get the last value manually using the BehaviorSubjects getValue() method.

One note to make about the code below is that the null block in the BehaviorSubject declaration represents the initial value of the BehaviorSubject upon initialization. You could either leave it, or pre-populate it with a value.

Service

EDITED: Corrected a couple of typing errors.

fwcUser: BehaviorSubject<FwcUser> = new BehaviorSubject<FwcUser>(null);
fwcUser$ = this.fwcUser.asObservable();

// Set the value of the fwcUser
updateFwcUser(user) {
    this.fwcUser.next(user);
}

Component

// Subscribe to the BehaviorSubject
ngOnInit() {
    this.fwcUserService.fwcUser$.subscribe(_fwcUser => {
        this.fwcUser = _fwcUser
    }
}

// Get the current (previously emitted) value manually
getFwcUser() {
    this.fwcUser = this.fwcUserService.fwcUser.getValue();
}
like image 150
joshrathke Avatar answered Oct 08 '22 13:10

joshrathke