Observable completed is not getting called when api returns 404, any alternate solutions when the api fails?

Viewed 197
  onSave(payload) {
this.loading = true;
const addIdp = this.identityProviderService.save(payload);
this.autoUnsubscribe(addIdp.subscribe((data) => {
  this.notificationsService.success(this.translateService.instant('idp.form.add-success'), '');
  this.ref.close(data);
}, (error) => {
  this.notificationsService.error(this.translateService.instant('idp.form.add-error'), '');
}, () => {
  this.loading = false;
}));

}

identityProviderService.save call has httpClient in it

3 Answers

inside your error block check status of error:

(error) => {
    if (error.status === 404) {
        // custom code goes here
    }
  this.notificationsService.error(this.translateService.instant('idp.form.add-error'), '');
}

This should do the work !!!

The observables by design do not trigger complete notification in case of an error notification. They are mutually exclusive, meaning if a stream errors out, it cannot complete or next thereafter. And if the stream completes, it cannot error or next thereafter.

So you either need to handle the error using catchError operator block or in the error callback block.

Try the following

onSave(payload) {
  this.loading = true;
  const addIdp = this.identityProviderService.save(payload);
  this.autoUnsubscribe(addIdp.subscribe(
    (data) => {
      this.loading = false;             // <-- set variable here
      this.notificationsService.success(this.translateService.instant('idp.form.add-success'), '');
      this.ref.close(data);
    }, 
    (error) => {
      this.loading = false;             // <-- and here
      this.notificationsService.error(this.translateService.instant('idp.form.add-error'), '');
    }
  );
}

Or you could use the finalize operator. From docs,

[it] will call a specified function when the source terminates on complete or error.

onSave(payload) {
  this.loading = true;
  const addIdp = this.identityProviderService.save(payload).pipe(
    finalize(() => this.loading = false)                   // <-- set variable here
  );
  this.autoUnsubscribe(addIdp.subscribe(
    (data) => {
      this.notificationsService.success(this.translateService.instant('idp.form.add-success'), '');
      this.ref.close(data);
    }, 
    (error) => {
      this.notificationsService.error(this.translateService.instant('idp.form.add-error'), '');
    }
  );
}

You should call finally before the subscribe, like so:

addIdp
  .finally(() => this.loading = false) // <<-- Call it here
  .subscribe((data) => {
    this.notificationsService.success(this.translateService.instant('idp.form.add-success'), '');
    this.ref.close(data);
  }, (error) => {
    this.notificationsService.error(this.translateService.instant('idp.form.add-error'), '');
  });

Related