Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to wait for second value from observable

Tags:

angular

rxjs

I have a situation where there is an auth guard and all routes are below it.

The auth service determines if the user is logged in or not by sending a request to the backend

private subject = new BehaviorSubject<User>(undefined)

  user$: Observable<User> = this.subject.asObservable().filter(user => !!user)

  isLoggedIn$: Observable<boolean> = this.user$.map(user => !!user.id)

constructor (private http: HttpClient) {
    http.get<User>(API['AUTH']['GET_AUTHENTICATED_USER'])
      .do(console.log)
      .subscribe(user => this.subject.next(user ? user : ANONYMOUS_USER))
  }

However auth guard does not seem to wait for the request to finish and gets a boolean false as the predefined value of (isLoggedIn$ observable)

auth guard

constructor (private authService: AuthService, private router: Router) {
    this.authService.isLoggedIn$.subscribe(isLoggedIn => this.isLoggedIn = isLoggedIn)
  }

is there a way to wait until the request completes or at least get the second value emitted through the observable?

like image 324
Petros Kyriakou Avatar asked Jan 25 '18 17:01

Petros Kyriakou


1 Answers

I believe the problem might come from using Behavioursubject here. From the docs:

Observers can subscribe to the subject to receive the last (or initial) value and all subsequent notifications.

As you'll see this means that you will receive data as soon as you subscribe, if there is a default value set.

Fortunately, the docs then offer:

If you are looking for BehaviorSubject without initial value see Rx.ReplaySubject

ReplaySubject doesn't send the initial value like BehaviourSubject does, though it does still offer the benefit of being able to subscribe 'late' and still receive the latest event.

BehaviorSubject and ReplaySubject docs.

like image 64
match Avatar answered Oct 14 '22 22:10

match