0

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?

2
  • Of course it's ready for the real world. When a server is down for whatever reason you won't get any configuration file, you will just get a 404 error. This is what's meant by this paragraph. Commented May 13, 2020 at 8:56
  • In my project (I control both server and client side) I found it necessary to pipe and transform the response due to the following reasons: 1. I wanted to have a class, not an interface returned. 2. Json type vs expected type mismatch. I believe response can be handled in similar way: pipe your response and add validation (or, if you intend to useclasses, youcan do this in a constructor) Commented May 13, 2020 at 9:13

2 Answers 2

1

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")

            }
        );
    }
Sign up to request clarification or add additional context in comments.

Comments

1

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');
      }
    }
  );
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.