Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to delay throwError with RxJS?

Tags:

rxjs

rxjs6

As expected, the following code emits 42 after 5 seconds:

const valueObservable = of(42).pipe(delay(5000));
valueObservable.subscribe((value) => console.log(value));

However, this throwing version errors immediately on subscription:

const throwingObservable = throwError(new Error('My Error')).pipe(delay(5000));
throwingObservable.subscribe((value) => console.log(value), (error) => console.error(error));

Why does this happen? How do I delay the throwing of the error?

like image 321
Lukas Renggli Avatar asked May 22 '19 07:05

Lukas Renggli


People also ask

How do you delay in RxJS?

In RxJS you can set the per-item delay in two ways: by passing a number of milliseconds into the delay operator (which will delay each emission by that amount of time), or by passing in a Date object (which will delay the beginning of the sequence of emissions until that absolute point in time).

What is throwError in RxJS?

RxJS throwError() operator is a creation operator used to create an observable that returns no items to the observer and immediately emits an error notification. In other words, we can say that the RxJS throwError() operator returns an observable that will notify an error. It just emits 'error' and nothing else.


3 Answers

I have found an (IMO) easier way of delaying the throwing of the error:

const throwingObservable = of(42).pipe(
    delay(5000),
    switchMap(() => throwError(new Error('My Error')))
);
throwingObservable.subscribe(
    value => console.log(value),
    error => console.error(error)
);
like image 134
nsacerdote Avatar answered Nov 09 '22 03:11

nsacerdote


I had a similar problem and found this github issue: https://github.com/Reactive-Extensions/RxJS/issues/648

Updated to my usecase it would be something like this:

const throwingObservable = throwError(new Error('My Error'))
  .pipe(
    materialize(),
    delay(4000),
    dematerialize()
  );

throwingObservable.subscribe(console.log, console.error);

It throws after a 4 seconds delay

like image 20
Vee6 Avatar answered Nov 09 '22 05:11

Vee6


Rxjs error is exception, it stop immediately the stream and let you catch it to react to something un expected. I guess you have no way to manipulate throwError stream except with catchError

Solution 1: Manipulate stream before throw the error.

const throwingObservable = throwError(new Error('My Error'));
timer(5000).pipe(mergeMap(e => throwingObservable))
  .subscribe((value) => console.log(value), (error) => console.error(error));

Solution 2: Catch the error, delay the stream, then dispatch it again

throwingObservable.pipe(
  // We catch the error, we delay by adding timer stream, then we mergeMap to the error.
  catchError(e => timer(1000).pipe(mergeMap(t => throwError(e)))
)).subscribe(console.log, console.error);

You can see it in action

like image 42
Yanis-git Avatar answered Nov 09 '22 03:11

Yanis-git