Search code examples
angularrxjsobservableangular9candeactivate

Angular CanDeactivateGuard: How to wait for the right or the next value of an Obersavble?


I have a Service that emits events:

export class MyService {
  private event = new BehaviorSubject<string>('init');
  event$ = this.event.asObservable();

  constructor() { }

  update(): void {
    this.event.next('update');
  }

  accept(): void {
    this.event.next('accept');
  }

  decline(): void {
    this.event.next('decline');
  }
}

I also have a CanDeactivateGuard that is triggered by a function in a Component:

canDeactivate(): Observable<boolean> {
  return this.service.event$.pipe(
    map(action => {
      return action === 'accept';
    })
  )
}

Now this works all fine. But I've got an issue:

This will always return the last event. So when nothing happened it will send init immediately. If update() was called, it will send update directly.

How can I make this to work so that it either:

  • … waits until accept or decline is send?
  • … waits until the next fresh Event is emitted?

Solution

  • You can skip the first emission from your BehaviorSubject with skip:

    this.service
      .pipe(
        skip(1),
        filter(a => ['accept', 'decline'].includes(a))
      )