Uko
Uko

Reputation: 13386

What is the safe way of using Angular's HttpClient request?

The official angular HttpClient guide suggests building an HTTP request service in the following way:

getConfig() {
  // now returns an Observable of Config
  return this.http.get<Config>(this.configUrl);
}

But also provides the following disclaimer:

Specifying the response type is a declaration to TypeScript that it should treat your response as being of the given type. This is a build-time check and doesn't guarantee that the server will actually respond with an object of this type. It is up to the server to ensure that the type specified by the server API is returned.

While I like the main concept of having a service that returns a well-defined type, the disclaimer shows that this is not completely ready for the real world where no one can rely on the format of a response of some external software system.

What is the best practice of implementing an HTTP request service in Angular that will reliably return objects of an expected type (in the current example Config) or provide a means to deal with errors?

Upvotes: 0

Views: 1120

Answers (2)

Barremian
Barremian

Reputation: 31125

Angular can assist in type declaration. But to have complete type assertion, you could leverage assertion features of Typescript. One quick way would be to utilize a type guard using type predicate.

private isConfig(config: Config | any): config is Config {
  return (config as Config).<property> !== undefined;
}

The <property> placeholder must be replaced with a property specific to the Config type. Then you could assert the type in runtime using the following

import { of, throwError } from 'rxjs';
import { switchMap } from 'rxjs/operators';

getConfig() {
  return this.http.get<Config>(this.configUrl).pipe(
    switchMap(response => {
      if (this.isConfig(response)) {
        return of(response);
      } else {
        return throwError('The reponse is not of type Config');
      }
    }
  );
}

Upvotes: 1

okihnjo
okihnjo

Reputation: 438

If I understood your question right, you want to have something implemented that handles the answer or more specifcly the error status of your backend whenever you make a invalid http request. An http requests returns an observable. You can subscribe to an observable and implement the next(), error() and complete() function. So for example if you have a login and make a http.post and your api returns (when login was succesfull) a token, you can handle that in you next function. Take a look at this example:

login(object) {
    var headers = new HttpHeaders({
        "Content - Type": "application / json" });
            this.http.post<LogAnswer>('localhost/api',
            {
                object
                //JsonObject
            },
            {
                headers
            }
        ).subscribe(
            (val) => {
                //stuff you do when it was accomplished,
                //val is the response you get from the api
            },
            (error) => {
                //error message when your login for example was not valid
                //this function will be triggered when you get a 401 for example
                window.alert("Not succesfull")

            }
        );
    }

Upvotes: 1

Related Questions