xkeshav
xkeshav

Reputation: 54072

Reset the Observable Timer on user action?

In my angular project, I need to refresh the token before it expires by doing user interaction. on UI we display session timeout message and a renew icon just before 5 minutes before it expires and when user click on renew icon we refresh the token and now it again checks the session with this new token and so on.

I was using setInterval() and clearInterval() and here is relevant code

@Compononet({})
export class AdminLayoutComponent implements OnInit {
    isRefreshingToken: boolean;
    interval: any;
    period: number;
    constructor() {
        this.notifyMinutes = 5; // in minutes
        this.isRefreshingToken = false;
        this.period = 60 * 1000;
        this.timer$ = Observable.timer(0, this.period);
    }

    ngOninit() {
        this.interval = <any>setInterval(() => this.checkSession(), this.period);
    }

    private checkSession() {
        // calculate the remaining time and display the message accordingly
        if (remainingTime < 5 minutes) {
            this.refreshTokenMethod.finally(() => {
                this.isRefreshingToken = false;
            }).subscribe() {
                this.isRefreshingToken = true;
            }
        }
    }
    ngOnDestroy() {
        if (this.interval) {
            clearInterval(this.interval);
        }

    }
}

This is working fine but I think Observables are a better tool to achieve the same. so tried this way

export class AdminLayoutComponent implements OnInit {

    timer$: Observable<any>;
    subscription: Subscription;

    constructor() {
        this.timer$ = Observable.timer(0, this.period);
    }

    ngOnInit() {
        this.subscription = this.timer$.subscribe((i) => {
            console.log('timer: ', i);
            this.checkSession();
        });
    }

    ngOnDestroy() {
        if (this.subscription) {
            this.subscription.unsubscribe();
        }
    }
}

Now problem is that when the user clicks on renew icon; I want to reset the timer again to check the timing.

How can I do this? or is it okay to run timer?

Upvotes: 2

Views: 5270

Answers (1)

Suresh Kumar Ariya
Suresh Kumar Ariya

Reputation: 9774

You need to use Subject Observable. Reset the timer using next().

export class AdminLayoutComponent implements OnInit {

    private reset$ = new Subject();
    timer$: Observable<any>;
    subscription: Subscription;

    constructor() {
        this.timer$ = this.reset$.pipe(
          startWith(0),
          switchMap(() => timer(0, 30000))
        );
    }

    ngOnInit() {
        this.subscription = this.timer$.subscribe((i) => {
            console.log('timer: ', i);
            this.checkSession();
        });
    }

   refreshTimer(): void {
      this.reset$.next(void 0);
    }

    ngOnDestroy() {
        if (this.subscription) {
            this.subscription.unsubscribe();
        }
    }
}

Also updated stackblitz code https://stackblitz.com/edit/angular-pnwh44

Upvotes: 3

Related Questions