title: Angular 2 dealing with multiple failed requests requiring an auth token refresh
body: <p>I am making an Angular 2 frontend for an API that uses access tokens. I am trying to use observables and ngrx/store with this.</p>
  
  <p>Logging in and out works fine and as intended. I have also written some code for when requests fail due the token expiring. This code works okay ordinarily but I run into trouble when I have multiple requests in a short span of time. This happens, for example, when I refresh the page and the app tries to fill two or three stores required across the app.</p>
  
  <hr>
  
  <p>My auth service has functions like these:</p>
  
  <pre><code>refreshLogin(): Observable&lt;any&gt; {
      const username = this.currentUser();
      let query = new URLSearchParams();
      query.set('refresh_token', this.refreshToken());
      query.set('grant_type', 'refresh_token');
      return this.getToken(username, query.toString());
  }
  
  private getToken(username: string, body: string): Observable&lt;any&gt; {
      const url = Config.AUTH_TOKEN_PATH;
      return this.http.post(url, body)
          .map((res: Response) =&gt; res.json())
          .do(
              (data) =&gt; {
                  const token = {
                      username: username,
                      accessToken: data.access_token,
                      refreshToken: data.refresh_token,
                      tokenType: data.token_type,
                      expiresIn: data.expires_in
                  };
                  this.store.dispatch(AuthActions.loginSuccess(token));
              },
              error =&gt; {
                  const description = error.json().error_description;
                  this.store.dispatch(AuthActions.loginError(description));
                  console.error(error);
              }
          )
      ;
  }
  </code></pre>
  
  <p>My REST function has a function like this:</p>
  
  <pre><code>get(url: string): Observable&lt;any&gt; {
      return this.http.get(url, new RequestOptions({ headers: this.authHeader() }))
          .catch(err =&gt; {
              if (err.status === 401) {
                  return this.auth.refreshLogin()
                      .switchMap(() =&gt; this.http.get(url, new RequestOptions({ headers: this.authHeader() })))
                      .catch(err2 =&gt; err2);
              } else {
                  console.log(err);
              }                
          })
          .map((res: Response) =&gt; res.json())
      ;
  }
  </code></pre>
  
  <p>I don't feel that the functions <code>currentUser()</code>, <code>refreshToken()</code>, and <code>authHeader()</code> are required to understand my question.</p>
  
  <hr>
  
  <p>If I have one failed request and the error is a 401, my app calls <code>refreshLogin()</code>, gets a new access token and stores it, and the original request is tried again with the new access token.</p>
  
  <p>If I have more that one failed request, and they are happening effectively at the same time, I run into issues. For example, say I have two GET requests. They both return 401 errors. They both fire off the <code>refreshLogin()</code> function. One <code>refreshLogin()</code> succeeds and stores a new access token; the other fails because the token being used to refresh is no longer valid. This stream of functions now fails, causing my app to stall.</p>
  
  <p>One solution would be to stack my GET requests in series, but that doesn't seem like it should have to be the case.</p>
  
  <p>I feel like there should be a solution where, on a failed GET (or other) request, the app triggers a call for the access token to be refreshed. The auth service would throttle these requests so there can only be one every couple of seconds or something. It fulfils this request, and the new access token is returned to all the requests to try again.</p>
  
  <p>Do you think this is a sensible approach or am I just trying to patch up an approach that was badly thought out to start with? How would you recommend making these parts interact?</p>