Angular 2 - Checking for server errors from subscribe

HttpAngularSubscribe

Http Problem Overview


I feel like this scenario should be in the Angular 2 docs, but I can't find it anywhere.

Here's the scenario

  1. submit a form (create object) that is invalid on the server
  2. server returns a 400 bad request with errors I display on the form
  3. after the subscribe comes back, I want to check an error variable or something (ie. if no errors > then route to newly created detail page)

I imagine it working something like this:

this.projectService.create(project)
	.subscribe(
		result => console.log(result),
		error => {
			this.errors = error
		}
	); 
}

if (!this.errors) {
	//route to new page
}

I'm very new to Angular 2 so this may come from my lack of understanding in how an Observable works. I have no issue with displaying that data on the form, but can't figure out how to see it within the ts component. I really just want to check the success/fail of the http create.

Http Solutions


Solution 1 - Http

As stated in the relevant RxJS documentation, the .subscribe() method can take a third argument that is called on completion if there are no errors.

For reference:

>1. [onNext] (Function): Function to invoke for each element in the observable sequence. >2. [onError] (Function): Function to invoke upon exceptional termination of the observable sequence. >3. [onCompleted] (Function): Function to invoke upon graceful termination of the observable sequence.

Therefore you can handle your routing logic in the onCompleted callback since it will be called upon graceful termination (which implies that there won't be any errors when it is called).

this.httpService.makeRequest()
    .subscribe(
      result => {
        // Handle result
        console.log(result)
      },
      error => {
        this.errors = error;
      },
      () => {
        // 'onCompleted' callback.
        // No errors, route to new page here
      }
    );

As a side note, there is also a .finally() method which is called on completion regardless of the success/failure of the call. This may be helpful in scenarios where you always want to execute certain logic after an HTTP request regardless of the result (i.e., for logging purposes or for some UI interaction such as showing a modal).

>Rx.Observable.prototype.finally(action) > >Invokes a specified action after the source observable sequence terminates gracefully or exceptionally.

For instance, here is a basic example:

import { Observable } from 'rxjs/Rx';
import 'rxjs/add/operator/finally';

// ...

this.httpService.getRequest()
    .finally(() => {
      // Execute after graceful or exceptionally termination
      console.log('Handle logging logic...');
    })
    .subscribe (
      result => {
        // Handle result
        console.log(result)
      },
      error => {
        this.errors = error;
      },
      () => {
        // No errors, route to new page
      }
    );

Solution 2 - Http

You can achieve with following way

    this.projectService.create(project)
    .subscribe(
        result => {
         console.log(result);
        },
        error => {
            console.log(error);
            this.errors = error
        }
    ); 
}

if (!this.errors) {
    //route to new page
}

Solution 3 - Http

Please note that the previous syntax with callbacks has been deprecated as of 6.4 and is going to be removed with 8.0. Instead of

of([1,2,3]).subscribe(
    (v) => console.log(v),
    (e) => console.error(e),
    () => console.info('complete') 
)

you should now use

of([1,2,3]).subscribe({
    next: (v) => console.log(v),
    error: (e) => console.error(e),
    complete: () => console.info('complete') 
})

https://rxjs.dev/deprecations/subscribe-arguments

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionStephanieView Question on Stackoverflow
Solution 1 - HttpJosh CrozierView Answer on Stackoverflow
Solution 2 - HttpPramod PatilView Answer on Stackoverflow
Solution 3 - HttpSteffenView Answer on Stackoverflow