2

Assume I have function which makes http call and returns Observable with user details.

If user doesn't exist it returns Observable which emits error.

// Get user by id
function getUser(id) {
  return Rx.Observable.create(obs => {
    if (id === 1) {
      obs.next('200 - User found');
      obs.complete();
    } else {
      obs.error('404 - User not found');
    }
  });
}

// This will print "200 - User found" in the console after 2 seconds
getUser(1)
  .delay(2000)
  .subscribe(r => console.log(r));

// !!! Delay will not work here because error emmited
getUser(2)
  .delay(2000)
  .subscribe(null, e => console.log(e));

Is there any way to delay Observable which emits error?

taras-d
  • 1,789
  • 1
  • 12
  • 29
  • why do you delay it? – Max Koretskyi Aug 01 '17 at 05:53
  • I want to delay every http request to the API regardless success it or not (to test how app will behave if response is too long) – taras-d Aug 01 '17 at 05:58
  • 1
    are you writing tests? you should usually use browser network tab throttling capabilities to emulate long requests – Max Koretskyi Aug 01 '17 at 06:00
  • 1
    I found 1 thread about mocking an api: https://stackoverflow.com/questions/38058141/how-can-a-mock-a-http-observable-in-angular2-for-when-no-api-is-written And another about how to simulate a timeout on an api call (it's not an error like you want but it can point you in the right direction): https://stackoverflow.com/questions/36719116/how-to-timeout-angular2-http-request – ADreNaLiNe-DJ Aug 01 '17 at 06:02
  • @Maximus, devtool network tab throttling is cool. But the problem not in http requests (it's just example). I'm curious why Observable doesn't delayed if it returns error. – taras-d Aug 01 '17 at 07:12
  • @taras-d, see if [my answer](https://stackoverflow.com/a/45431627/2545680) makes sense. – Max Koretskyi Aug 01 '17 at 07:34

1 Answers1

2

I'm curious why Observable doesn't delayed if it returns error

Here is the source code of the delay operator:

class DelaySubscriber<T> extends Subscriber<T> {
  ...

  protected _next(value: T) {
    this.scheduleNotification(Notification.createNext(value)); <-------- notification is scheduled
  }

  protected _error(err: any) {
    this.errored = true;
    this.queue = [];
    this.destination.error(err); <-------- error is triggered immediately
  }

  protected _complete() {
    this.scheduleNotification(Notification.createComplete());
  }
}

Just as with every other operator, delay subscribes to the source stream - getUser() in your case - and notifies the listener. You can see from the source code that it doesn't schedule notification when an error occurs and trigger the error method on the observable immediately.

Here you can learn more about delay operator.

I want to delay every http request to the API regardless success it or not (to test how app will behave if response is too long)

I recommend using throttle capabilities of the Chrome Debugging Tools (network tab).

Max Koretskyi
  • 101,079
  • 60
  • 333
  • 488