Angular 6 ng-idle

21,513

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;
    }
}
Share:
21,513
Jim Grant
Author by

Jim Grant

I have had a varied background covering over 30 years in the IT industry: from electronic design and production through to website design and development. I have been programming from the age of 11 and have experience in different levels of programming language. My R&D background means that I have the ability to solve problems where giving up isn't simply an option. I can mix and match technology and programming languages as deemed appropriate to the task in hand. My main goal or belief is that computers are meant to make our lives easier, not harder, and if there is anything I can do to help that - I will.

Updated on September 27, 2020

Comments

  • Jim Grant
    Jim Grant almost 4 years

    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.

  • Jim Grant
    Jim Grant over 5 years
    A good idea, but I also have multiple routing.ts files. I've gone about it differently, see below.
  • Jim Grant
    Jim Grant over 5 years
    Yes I know the reset() function is no longer required in this case.
  • ajay hariyal
    ajay hariyal almost 5 years
    Great code, for more clarity, follows this link for install dependencies. hackedbychinese.github.io/ng2-idle and then use [link] (stackoverflow.com/users/436315/jim-grant) for multi tab idle. Great work @Jim Grant
  • Yunnosch
    Yunnosch over 3 years
    Is this an extremely verbose "Thanks" or is there an actual answer to the question hidden here?