Angular HTTP client implementation with retry logic using alternative access token

Dealing with access tokens and refresh tokens for multiple APIs can be tricky. The challenge arises when an access token expires and needs to be updated without disrupting the functionality of the application.

The current solution involves manually updating the access token in every function that requires it, which is not ideal as it may lead to errors if the refresh token also expires.

getAllBuckets(account: GetAllBucket){
    const {project, accessToken} = account
    const qs = new URLSearchParams({project})
    return this.http.get(`${this.urlGoogleStorage}?${qs.toString()}`, { headers: {Authorization: `Bearer ${accessToken}`}}).pipe(
      catchError((error) => {
        if(error.status == 401) this.auth.updateAccessToken(account);
        return throwError(() => error)
      })
    )
  }

Is there a more efficient way to handle access token expiration and renewal across multiple APIs?

Answer №1

Angular's Http interceptor feature is perfect for handling these types of scenarios. With an interceptor, you can intercept every request made from your Angular project, acting as a middleware for HTTP calls.

To create an interceptor, you can follow this example:

@Injectable({
  providedIn: 'root',
})
export class TokenInterceptorService implements HttpInterceptor {
  constructor(private auth: TokenService) {}
  intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
let token = this.auth.getToken();

// Include your token in every request
request = request.clone({
  setHeaders: {
    Authorization: `Bearer ${token}`,
  },
});

return next.handle(request).pipe(
  catchError(res=>{
    if(res instanceof HttpErrorResponse && res.status===401){
      // Your custom logic to update token can go here
      let newToken = this.auth.updateAccessToken(account);

      request = request.clone({
        setHeaders: {
          Authorization: `Bearer ${newToken}`,
        },
      });
      
      next.handle(request);
    }else{
      return throwError(res);
    }
  })
);

}

You need to provide this interceptor in the root module like so:

@NgModule({
declarations: [..],
imports: [
...
],
providers: [
   {
     provide: HTTP_INTERCEPTORS,
     useClass: TokenInterceptorService ,
     multi: true,
   },
 ],

Now, every HTTP call made by a service that is provided in the root will pass through this interceptor. You have the flexibility to modify requests based on your requirements within the interceptor service.

For more information, refer to the documentation here.

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

Develop a simple application using the MEAN stack framework

I am new to Node.js and Express and I am interested in creating a basic AngularJS application. However, I am unsure of where to begin in terms of file organization. My desired file structure is as follows: - public ----- app ---------- components -------- ...

What is the best way to bring in a SCSS file within another SCSS file?

When working with SCSS, I find myself using a lot of variables. To keep things organized, I create a separate file that contains all of my SCSS variables. The next step is to import this file into other SCSS files. Here's what I tried: Create a fil ...

Can one retrieve an express session using the sessionID given?

I have a NodeJS Express application with express-session that works well, however, it needs to be compatible with a cookie-less PhoneGap app. My question is: Can I access the data in an express session using the sessionID? I was thinking of adding the se ...

Adding a script to the head of a Next.js page by using the Script component

I need assistance with inserting tracking code from Zoho application into the Head section of each page in my Next.js application. I am currently using a _document.tsx file and following the instructions provided by Next.js regarding the use of the Next.js ...

What is the best way to transfer data from a div tag to an li tag using JavaScript?

https://i.stack.imgur.com/se2qk.pngI am attempting to change the div tag content to li tag. Here is a snippet of the code from inspect for reference. I need to remove the div tag with the "domTitle" class. <li style="display: inline;" id="list_name"> ...

Signing in to a Discord.js account from a React application with Typescript

import React from 'react'; import User from './components/User'; import Discord, { Message } from 'discord.js' import background from './images/background.png'; import './App.css'; const App = () => { ...

Warning: Angular.js encountered a max of 10 $digest() iterations while iterating through array slices. Operation aborted

JSbin: http://jsbin.com/oxugef/1/edit I am attempting to slice an array into smaller subarrays and iterate through them in order to create a table of divs that are evenly divided. Unfortunately, there seems to be an issue where I am unknowingly overwritin ...

Unlock the Power of Angular with Custom Decorators: Accessing ElementRef Made Easy

I am currently working on implementing a decorator for Host CSS Variable Binding in Angular5. However, I am facing difficulties in properly implementing it with the given code. Is there a way to define ElementRef from within the decorator itself? export f ...

Tips for achieving an AJAX-like appearance in jQuery for my code

The question may seem a bit confusing, but here's the basic idea: I'm currently working on a JavaScript library and I want to incorporate some of jQuery's style. I have a function that will take in 3 parameters, and I want it to work simila ...

Learn how to use sanitizer.bypassSecurityTrustStyle to apply styling to Pseudo Elements before and after in a template

Currently, I am attempting to add style to a pseudo element :after <a class="overflow">{{item?.eco}}</a> My goal is to modify the background color of a:after, and I believe this adjustment needs to be made in HTML. I've been thinking ...

Retrieving checkbox list values using jQuery

I am working with a div that contains some checkboxes. I want to write code so that when a button is clicked, it will retrieve the names of all the checked checkboxes. Can you provide guidance on how to achieve this? <div id="MyDiv"> .... <td> ...

Challenges with Vuex and updating arrays using axios

I am currently facing a challenge with VueJS Vuex and Axios: The issue arises when I retrieve an array with Axios and loop through it to populate its children this way: "Rubriques" has many self-relations, so one rubrique can have multiple child rubriques ...

Having trouble saving text in a textbox?

Is there a way to store text in a text box for future use? Every time I reload the page, the text in the box disappears. I have attempted the following solution: <td align='left' bgcolor='#cfcfcf'><input type="text" name="tx ...

Tips for resolving the error message "cannot read property of undefined"

I've been working on coding a Discord bot and I keep encountering an error when trying to check if "mrole" has the property "app". It's not functioning as expected and I'm puzzled by why this is happening. My intention is to retrieve the te ...

Using single quotation marks in Javascript

When the variable basis contains a single quotation mark, such as in "Father's Day", I encounter an issue where the tag is prematurely closed upon encountering the single quotation mark. 'success' : function(data) { div.innerHTML = &apo ...

Tips for setting multiple states simultaneously using the useState hook

Exploring the use of multiple states handled simultaneously with the useState hook, let's consider an example where text updates based on user input: const {useState} = React; const Example = ({title}) => { const initialState = { name: &a ...

Are there any downsides to utilizing the jQuery Load function?

I am in the process of creating a website that displays sensor data. I plan to incorporate a HighChart line chart to showcase this data. Since my website is relatively simple in terms of content, I have decided to consolidate all elements onto one page inc ...

Best Practices for Angular and Managing Database Access

By now, I have a good understanding that angular.js is a client-side framework, which means any database communication involves sending requests to a server-side script on the server using methods like get/post (with node, php, asp.net, or other technologi ...

Incorporating unique HTML5/iframe widgets into your Facebook Timeline and Tab Pages

I have a unique widget that users can easily integrate into their websites using the HTML/iframe code generated by my app. Now, I am looking for a way to allow users to also add this widget to their Facebook Company Pages. The widgets are accessible th ...

The AngularJS error message states that there is an issue because the $resource function is

I am currently facing an issue with my controller, specifically the error message: TypeError: $resource is not a function This error is pointing to the line var Activities = $resource('/api/activities'); app.controller('AddActivityCtrl& ...