angularkeep-aliveng-idle

Angular 6 ng-idle


I have an Angular Project which is working well and I'm implementing NG-IDLE and KeepAlive in order to keep the session fresh and to log a user out before the API session expires.

My issue is that the ng-idle is also operating on the login page, which is obviously not required, as when it does time out, it will take the person to the login page.

So I have the ng-idle and KeepAlive up and running in my app.component.ts but since I'm using lazy loading, I also have an authentication.module.ts and a login.component.ts.

The code in my root app.component.ts is as follows:

import { Component } from '@angular/core';

import { Idle, DEFAULT_INTERRUPTSOURCES } from '@ng-idle/core';
import { Keepalive } from '@ng-idle/keepalive';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {

    idleState = 'Not started.';
    timedOut = false;
    lastPing?: Date = null;

    constructor(private idle: Idle, private keepalive: Keepalive) {

        // sets an idle timeout of 5 seconds, for testing purposes.
        idle.setIdle(5);

        // sets a timeout period of 5 seconds. after 10 seconds of inactivity, the user will be considered timed out.
        idle.setTimeout(5);

        // sets the default interrupts, in this case, things like clicks, scrolls, touches to the document
        idle.setInterrupts(DEFAULT_INTERRUPTSOURCES);

        idle.onIdleEnd.subscribe(() => this.idleState = 'No longer idle.');

        idle.onTimeout.subscribe(() => {
            this.idleState = 'Timed out!';
            this.timedOut = true;
        });

        idle.onIdleStart.subscribe(() => this.idleState = 'You\'ve gone idle!');
        idle.onTimeoutWarning.subscribe((countdown) => this.idleState = 'You will time out in ' + countdown + ' seconds!');

        // Sets the ping interval to 15 seconds
        keepalive.interval(15);

        keepalive.onPing.subscribe(() => this.lastPing = new Date());

        this.reset();
    }

    reset() {
        this.idle.watch();
        this.idleState = 'Started.';
        this.timedOut = false;
    }
}

I know I need to call idle.unwatch in order to prevent idle running and idle.watch when I need it to, but how can I either call these from the login or authentication module, or can I detect from the root app.component.ts?

As no doubt you can tell that I'm new to Angular, so apologies if this is a rookie question.


Solution

  • Since there are always more than one way to skin a cat, here's my own solution to this issue. I hope someone else finds it useful in the future.

    import { Component } from '@angular/core';
    
    import { Location } from '@angular/common';
    import { Router } from '@angular/router';
    
    import { Idle, DEFAULT_INTERRUPTSOURCES } from '@ng-idle/core';
    import { Keepalive } from '@ng-idle/keepalive';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    
    export class AppComponent {
    
        currentPath: String;
    
        idleState = 'Not started.';
        timedOut = false;
        lastPing?: Date = null;
    
        constructor(private idle: Idle, private keepalive: Keepalive, location: Location, router: Router) {
    
            // sets an idle timeout of 5 seconds, for testing purposes.
            idle.setIdle(5);
    
            // sets a timeout period of 5 seconds. after 10 seconds of inactivity, the user will be considered timed out.
            idle.setTimeout(5);
    
            // sets the default interrupts, in this case, things like clicks, scrolls, touches to the document
            idle.setInterrupts(DEFAULT_INTERRUPTSOURCES);
    
            idle.onIdleEnd.subscribe(() => this.idleState = 'No longer idle.');
    
            idle.onTimeout.subscribe(() => {
                this.idleState = 'Timed out!';
                this.timedOut = true;
            });
    
            idle.onIdleStart.subscribe(() => this.idleState = 'You\'ve gone idle!');
            idle.onTimeoutWarning.subscribe((countdown) => this.idleState = 'You will time out in ' + countdown + ' seconds!');
    
            // Sets the ping interval to 15 seconds
            keepalive.interval(15);
    
            keepalive.onPing.subscribe(() => this.lastPing = new Date());
    
            // Lets check the path everytime the route changes, stop or start the idle check as appropriate.
            router.events.subscribe((val) => {
    
                this.currentPath = location.path();
                if(this.currentPath.search(/authentication\/login/gi) == -1)
                    idle.watch();
                else
                    idle.stop();
    
            });
        }
    
        reset() {
            this.idle.watch();
            this.idleState = 'Started.';
            this.timedOut = false;
        }
    }