title: Angular : get api access token before any http request
body: <p>I'm building an app with Angular 4 (Angular 2).</p>
  
  <p>I built an API that need an OAuth access token.</p>
  
  <p>The token is given from calling this route :</p>
  
  <blockquote>
    <p>GET /oauth/v2/token?client_id=CLIENT_ID&amp;client_secret=CLIENT_SET&amp;grant_type=client_credentials</p>
  </blockquote>
  
  <p>The token provided will expired after 3600 seconds, therefore the client app will have to require a new access token (using provided refresh token or not).</p>
  
  <p>In AngularJs (1.*) i was using interceptor for this matter. Since interceptors are not part of Angular anymore.</p>
  
  <p>Let say i have 3 services :</p>
  
  <ul>
  <li>UserService</li>
  <li>ApiService</li>
  <li>OAuthService</li>
  </ul>
  
  <p>i figure out 2 options :</p>
  
  <p><strong>Option 1 :</strong></p>
  
  <p>ApiService will extend Http provider as mentioned in this <a href="https://long2know.com/2017/01/angular2-http-interceptor-and-loading-indicator/" rel="nofollow noreferrer">article</a>.</p>
  
  <p>Someone on stackoverflow was trying to use a similar 
  <a href="https://stackoverflow.com/questions/43982029/angular-2-refresh-token-before-custom-http-request">solution</a>.</p>
  
  <p>Therefore in any http request i'll be able to call the server to request a new access token, if expired of course. All the logic regarding the access token (cookie storage, expire, valid access, etc.) will be in OAuthServie.</p>
  
  <p><strong>Option 2 :</strong> </p>
  
  <p>ApiService will not extend Http but simply use it as a service.</p>
  
  <p>Here the exemple :</p>
  
  <p><strong>UserService</strong></p>
  
  <pre><code>export class UserService {
  
    constructor(private apiService: ApiService) { }
  
    getUsers(): Promise&lt;User[]&gt; {
      return this.apiService.get('/users').toPromise()
        .then(response =&gt; response.json() as User[])
        .catch(this.handleError);
    }
  
    /* ... */
  
  }
  </code></pre>
  
  <p><strong>ApiService</strong></p>
  
  <pre><code>export class ApiService {
  
    constructor(private http: Http, private oAuthService: OAuthService) { }
  
    /**
     * name: get
     * params:{String}  url
     */
    get(url: string) {
      // Using Observable or Promise (promise is used as pure exemple here)
      // GET ACCESS TOKEN
      return this.oAuthService.getAccessToken().then((accessToken) =&gt;
        // ADD TOKEN TO HEADER
        let headers = new Headers();
        headers.append('Authorization', 'Bearer ' + accessToken);
        // CALL API (/api/users for exemple)
        return this.http.get(environment.apiEndpoint + url, {
          headers: headers
        });
      );
    }
  </code></pre>
  
  <p>}</p>
  
  <p><strong>OAuthService :</strong></p>
  
  <pre><code>export class OAuthService {
  
    private accessToken: string;
  
    constructor(public cookieService: CookieService, public http: Http) { }
  
    getAccessToken() {
      this.accessToken = this.cookieService.get('access_token');
      if(!hasValidAccessToken) {
        return this.http.get('/oauth/v2/token?client_id=CLIENT_ID&amp;client_secret=CLIENT_SET&amp;grant_type=client_credentials').toPromise()
          .then(response =&gt; response.json())
          .catch(this.handleError);
        }
      }
      else {
        return this.accessToken;
      }
    }
  
    /**
     * Check validity of token, exist, expire, etc.
     */
    hasValidAccessToken() {}
  
  }
  </code></pre>
  
  <p>So i would like to know which option would be the most proper way to do such thing? Otherwise what other option would you advise taking into consideration than the access token will be expired after 3600 seconds?</p>
  
  <p>Both options would require promise or observable to be able to request the api call. Otherwise if access token is not yet obtained the api call will throw an unauthorised exception. Promise would be the way to go since it is a single event, am i right?</p>
  
  <p>Please advise me, i'm getting a little bit confused with all those choices.</p>