0

I'm trying to execute a service function in the background that gets the refresh token from the server each 4 minutes.

 @Injectable()
 export class RefreshTokenService {
 time: any;
 token: string;
 email: string;
 credentials: any;

 constructor(private http: HttpClient) {
 }


  getToken(): string {
   const credentials = localStorage.getItem('credentials');
   if (credentials) {
     const parsedCredentials = JSON.parse(credentials);
     const token = parsedCredentials.token;
     return token;
   }
   return null;
  }

 refreshToken(token: string) {
   const tokenJson: any = {'token': token};
   this.http.post('/api-token-refresh/', tokenJson,   httpOptions).subscribe(response => {
     const data = JSON.parse(JSON.stringify(response));
     this.credentials = JSON.parse(localStorage.getItem('credentials'));
     this.credentials.token = data.token;
     localStorage.setItem('credentials',  JSON.stringify(this.credentials));
   });
 }}

Now i'm executing the refreshToken() in the app.component.ts inside ngOnInit() , so it executes every time i load a page in the app, and it works as expected, but i haven't found a proper way to call the refreshToken() each 4 minutes in the background.

i already looked at this but it seem not to work... How to call function every 2 mins in angular2?

med.b
  • 465
  • 2
  • 12
  • 21

3 Answers3

1

The best way is to use interval and switchMap operator.

First, return an observable from the refreshToken function. Use map operator to do all other stuff like transforming data, storing in localstorage etc in refreshToken() method.


import { interval, pipe } from 'rxjs'; 
import { map, switchMap } from 'rxjs/operators';

.....

refreshToken(token: string) {
   const tokenJson: any = {'token': token};
   return this.http.post('/api-token-refresh/', tokenJson,   httpOptions);
};

checkingTokenOnInterval(){
     const intervalTime = 4*60*1000;
     const token = 'sdfsdf';
     interval(intervalTime).pipe(switchMap(() => this.refreshToken(token))).subscribe(()=>{
                 //do something 
     });
}

Use checkingTokenOnInterval() for calling refreshToken call on every 4 minutes.

Vikash Dahiya
  • 5,741
  • 3
  • 17
  • 24
  • Should i call `checkingTokenOnInterval()` inside the `ngOnInit()` in the `app.component.ts` ? – med.b Jan 19 '19 at 18:59
  • yes if you want to call refreshToken on every 4 min – Vikash Dahiya Jan 19 '19 at 19:01
  • It does indeed execute after the period set in `intervalTime`,but it does execute only once and after that i gives this error `ERROR TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.` have an idea how to fix it ? – med.b Jan 19 '19 at 19:38
  • I m not sure about this error, probably there will be some minor syntax error in rxjs code , but you can check this [stackblitz-demo](https://stackblitz.com/edit/rxjs-uqzdew?devtoolsheight=60) – Vikash Dahiya Jan 19 '19 at 19:56
1

Be aware of requests that are sent right after refresh token request with old valid token. I recommend to use interceptor and queue all requests sent after refreshToken. Wait until refreshToken comes and then send queue requests.

Another way - catch 401 Error -> copy request -> refreshToken -> send copy of request.

0

You can achieve it using RxJS/timer https://rxjs-dev.firebaseapp.com/api/index/function/timer

    this.refreshTokenService.refreshToken()
        .pipe
            tap(() => {
                // every 4 minutes refresh the discovery service
                const interval = 4 * 60 * 1000;
                timer(interval, interval).subscribe(() => {
                    this.refresh().subscribe();
                });
            })
        )
        .toPromise();
skdonthi
  • 1,308
  • 1
  • 18
  • 31