Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check API response data with interface in Typescript Angular

I have an app that when the user logs in he received some data as a response, but if the response is not what I expect, the app crashes.

Let me show you the following:

I created an interface to tell Typescript the data I expect.

export interface AuthResponseData {
  token: string;
  expires: string;
  role: number;
}

Then I created a method to send the login data to the server.

login(user: string, password: string){
  return this.http.post<AuthResponseData>(
    'https://localhost:44344/api/auth', { user: user, pwd: password }
  ).pipe(
    catchError(this.handleError),
    tap(resData => { this.handleAuthentication(resData.token, resData.expires, resData.role)})
  );
}

I was expecting that if the response from the server didn't match the interface then the Angular would redirect to catchError. But doesn't happen.

Now my question is: Is there any way to check if an API response is equal to the interface and throw an error if is not. Or what I'm asking isn't possible?

UPDATE:

After searching I discover that the interfaces disappear on run time, so there is no way to compare the api response with the interface (to the best of my knowledge). But I keep searching for a way to check the api response in a dynamic way. I think it is not really secure depending on api response to be always right. So I should check the API response. How can I do that?

Hope you can help me, thanks :)

like image 942
Proz1g Avatar asked Feb 12 '20 14:02

Proz1g


2 Answers

You can use promise and thenable() function to catch the error if your api response is not as per your requirement.

login(user: string, password: string){
        return this.http.post('https://localhost:44344/api/auth', { user: user, pwd: password })
        .pipe(map(response => {
            this.checkForValidResponse(response)
            .then( onResolve =>{
                //Came here is your response is according to your requirements
            })
            .catch(onReject =>{
                //Catch the error and treat it as error if your resposne is not according to your requirements
            });
        }));            
    }
    checkForValidResponse(responseOfApi){
        return new Promise((resolve, reject)=>{
            //Your Code for To Check wether API response is Valid OR not . 

            //If YOur API reponse is valid then **
            resolve(Your message to send back)

            //IF your API resopnse is invalid
            reject(Your message to send back)
        })
    }

Hope this is what you are looking for .

like image 39
Pushprajsinh Chudasama Avatar answered Sep 29 '22 07:09

Pushprajsinh Chudasama


As you already noticed, an interface is purely TypeScript, it doesn't exist in JavaScript and is not emulated in any way (just like private, protected, public, and some other things). The type checking in TypeScript just allows to have a "fail fast" logic (you don't have to run the app to notice that your own code or a third party library is being misused, it fails at compilation time).

Your Angular app is just an UI, there are no critical operations involved (they should live in your backend), so I don't think it's a good idea to throw an error because of a type mismatch, instead of just trying to satisfy the user as much as possible. According to me a backend should validate a client input, and a client should try to adapt with a backend service.

That being said, there is a draft for JSON validation here https://json-schema.org/ and some libraries implement it (e.g: https://github.com/epoberezkin/ajv). This would allow you to get the desired behavior.

like image 170
Guerric P Avatar answered Sep 29 '22 08:09

Guerric P