Optimal strategies for managing server-side validation/errors in Angular applications

Back in the day, I used to retrieve HTTP responses with a TypeScript object.

validateTokenHttp(token: string): Observable<User> {
    return this.http.get<User>(`${environment.api}/auth/verifyToken/${token}`);
}

Sometimes it would return a User object, or an Account Not Verified message, or an Account Not Valid response, or something else entirely.

The big question is, what is the best approach to handle these various responses?

Here are some possibilities I've been considering:

  1. Send the response with a status code of 401 or another,

    this.validateTokenHttp(token)
        .subscribe(
          (user) => {
              // perform successful operation
          },
          (error) => {
             if(error.status == 401){
                 console.log(error.error); // handle the exception
             }
          }
        );
    
    • Response
      // Status Code: 401
      {message: "Account Not Verified"}
      

    NOTE: In this scenario, we are referring to the status code 401, but there could be multiple validation scenarios on the server that don't align with 401.

  2. Include validation errors within the HTTP response with a status code of 200

    validateTokenHttp(token: string): Observable<any> {
        return this.http.get<any>(`${environment.api}/auth/verifyToken/${token}`);
    }
    
    getUser(){
        this.validateTokenHttp(token)
        .subscribe(data=>{
            if(data.success == true){
            //perform successful operation
            }
            else{
            //handle the exception
            }
        });
    }
    
    • Response 1

      //Status Code: 200
      {success: true, data: "--User details JSON object"}
      
    • Response 2

      //Status Code: 200
      {success: false, message: "Account Not Verified"}
      

If we opt for solution 2, we would need to change the return type from

validateTokenHttp(token: string): Observable<User>
to
validateTokenHttp(token: string): Observable<any>
. However, using the <any> type might not be the ideal choice.

Is there a way to expect two possible objects?

Observable<User || CustomErrorObject>

How can we ensure that we receive a User object?

Can someone please advise on the best practice for handling these types of server validations and responses?

Answer №1

There isn't just one definitive answer to this question, but I'll share my perspective on it.

If I had to choose, I would go with option 1.

Firstly, it is logical to return a 401 status code when a user is unauthorized. When developing an API, clarity and conformity to standards are essential to ensure the ease of use for others.

Secondly, I always opt to handle HTTP errors within the observable using the catchError operator. This approach ensures that errors do not disrupt the flow of the stream. By handling errors appropriately, you can keep the observable running smoothly and determine the desired outcome of the stream.

Additionally, you have the flexibility to return:

Observable<User | ErrorObject>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Searching for the position of different size values according to their specific value

information = { boxNoTo: 1, boxNoFrom: 1, size: 'M', } items = [{ size: 'M', },{ size: 'M', },{ size: 'S,M,L,XS', boxNoTo: 1, boxNoFrom: 1, country: 'CA', name: 'Josh' }] This is what I have don ...

What are the steps for designing personalized syncfusion grid-columns while still preserving the built-in search functionality of syncfusion?

Looking to transform the data coming from the backend, specifically mapping a user's status which is represented as a number to its corresponding string value. Considered using typescript for this mapping task, but it interferes with syncfusion' ...

Tips for incorporating nested generics in Typescript

Currently, I am developing a straightforward activity execution framework that allows developers to define activities which can be executed within a workflow. To enhance type safety and boost developer productivity by utilizing type hints, I aim to incorp ...

What is the best way to ensure that my mat-slide-toggle only changes when a specific condition is met?

I'm having an issue with a function that toggles a mat-slide-toggle. I need to modify this function to only toggle when the result is false. Currently, it toggles every time, regardless of the result being true or false. I want it to not toggle when t ...

Encountered an error while attempting to load module script

Upon launching an Angular application on Heroku, a situation arises where accessing the URL displays a blank page and the console reveals MIME type errors. The error message reads: "Failed to load module script: The server responded with a non-JavaScrip ...

Having trouble centering an icon in a cell within AG Grid?

I am struggling with aligning my checkmarks within the cells of my AG Grid. Currently, they are all left aligned but I need them to be centered. Adjusting the alignment for text is not an issue, but I can't seem to center the material icons. It appear ...

Error: No provider found for _HttpClient in the NullInjector context

Hello everyone, I am new to Angular and currently facing an issue that has me stuck. The error message I'm receiving is as follows: ERROR NullInjectorError: R3InjectorError(Standalone[_AppComponent])[_ApiCallServiceService -> _ApiCallServiceService ...

When a link containing an ID hash in the URL is opened in a new tab, the ID within the link

Is there a way to create a link that leads to http://localhost:4300/?id=RTnySsxr8T2lPIihu2LqMw==&lang=en-us Upon clicking the link, a new tab opens in the browser with that URL. The issue arises when the hashed ID in the address bar changes to http:/ ...

What could possibly be causing routing issues in Angular 2?

Can anyone explain to me why the routing feature is not functioning properly in Angular 2? I am attempting to display a component when the URL path is empty. Below is the code snippet: http://plnkr.co/edit/Vgc2bB7Lc8h9XsuhIg6X?p=preview import { NgModul ...

What is the proper error type to use in the useRouteError() function in react-router-dom?

In my React project, I am utilizing the useRouteError() hook provided by react-router-dom to handle any errors that may arise during routing. However, I'm uncertain about the correct type for the error object returned by this hook. Currently, I have ...

Oops! The last loader did not provide a Buffer or String as expected

After converting my GraphQL query and HOC component to typescript, I encountered the following error: ERROR in ./client/components/Protected.Route.tsx Module build failed: Error: Final loader (./node_modules/awesome-typescript-loader/dist/entry.js) didn ...

Can you run both Angular 6 and AngularJS 1.6 applications on the same computer?

Trying to juggle the development of an Angular 6 app and an AngularJS 1.6 app on the same machine has posed a challenge for me. My current situation involves working on two projects simultaneously - one being a new project utilizing Angular 6 and Angular ...

Polling with RxJs, handling errors, and resetting retryCount with retryWhen

I am currently working on setting up a polling strategy that functions as follows: Retrieve data from the server every X seconds If the request fails, show an error message: "Error receiving data, retry attempt N°"... And retry every X seconds for a maxi ...

What is preventing this from being a function?

It appears that the authenticationProvider is missing for some reason. @autoinject() export class ProviderManager implements AuthenticationManager { constructor( private container: Container ){ } public authenticate( creds: Credentials ): Promis ...

Angular 2 - Dependency Injection failing to function

I have created two different implementations for an interface and assigned them as providers for two separate components. However, I am encountering the following error: Error: Can't resolve all parameters for ChildComponent: (?). What could be the i ...

Utilize the up and down arrow keys to scroll through a description list in React

If you want to navigate through the list of Description Details using the tab and shift tab keys, it can be done easily. The default behavior allows for smooth navigation. <dl> <dt style={{ textAlign: "center" }}>Beast of Bodmin< ...

Is it possible in Typescript to pass method signature with parameters as an argument to another method?

I am working on a React app where I have separated the actions into a different file from the service methods hoplite.actions.ts export const fetchBattleResult = createAsyncThunk<Result>( 'battle/fetchBattleResult', HopliteService.battleRe ...

Is it possible to load the surrounding markup in Angular before the guards are resolved upon the initial load of the router-outlet?

Within our Angular 12 application, we have implemented guards that conduct checks through API calls to the backend in order to validate the user's permissions for accessing the requested route. The default behavior of these guards follows an all-or-no ...

Using Typescript with NodeJs

As I work on my app.ts file, I prefer using this approach. However, I’ve been encountering some problems with .d.ts imports, which are preventing me from accessing the full API of express. The main issue is that in Webstorm2016 (I haven’t tested it on ...

Asserting types for promises with more than one possible return value

Struggling with type assertions when dealing with multiple promise return types? Check out this simplified code snippet: interface SimpleResponseType { key1: string }; interface SimpleResponseType2 { property1: string property2: number }; inter ...