12

My AlertService has private subject = new Subject<Alert>();. I want to autocratically clear alert after 5 seconds. I can do it with using setTimeout() like this:

autoClear(alertId?: string) {
   setTimeout(
      () => this.subject.next(new Alert({alertId})),
   5000);
  }

I tried to do that more elegant and I created this code:

autoClear(alertId?: string) {
    const delay = new Observable(x => {
      x.next();
    }).delay(5000).subscribe(() => {
      this.subject.next(new Alert({alertId}));
      delay.unsubscribe();
    });
  }

Both of example works but it doesn't look like a proper way of using RxJS. How can I improve it?

Xalion
  • 623
  • 9
  • 27
  • 1
    I think you are done with the best. Go with any one of the your way. both are good. But I am not sure which one is best for performance. – Ramesh Rajendran Jul 25 '18 at 10:36
  • I don't understand - you are emitting a new alert after 5 seconds - how is this same as clearing alerts? – Wand Maker Jul 25 '18 at 11:18
  • @WandMaker https://stackblitz.com/edit/angular-2-5-alerts?file=app%2F_services%2Falert.service.ts – Xalion Jul 25 '18 at 12:22

2 Answers2

3
new Observable(x => {
  x.next();
}).delay(5000);

is the correct way. The new way with the pipeables operators is

new Observable(x => {
  x.next();
}).pipe(delay(5000));
1

Maybe a more readable version could be using timer and take(2) like this:

function autoClear(alertId: any) {
  timer(0, 1000)
    .pipe(
      take(2),
    )
    .subscribe(i => i === 0
      ? subject.next(`start: ${alertId}`)
      : subject.next('stop')
    );
}

With take(2) you make it obvious that there're only two states. The two subject.next() calls are right next to each other so you can quickly see what you're sending in next() later.

See live demo: https://stackblitz.com/edit/rxjs6-demo-8ez3af?file=index.ts

martin
  • 93,354
  • 25
  • 191
  • 226