Search code examples
javascriptangularsetintervalcleartimeout

How to implement Idle time in angular using native JS code?


I have to detect user's idle time out in my application. My application is using both native javascript and angular. in my HTML + JavaScript page i implemented below:

<script>
var inactivityTime = function () {
    var time;
    document.onmousemove = resetTimer;
    document.onkeypress = resetTimer;
    document.onclick = resetTimer;
    document.onwheel = resetTimer;

    function callApi() {
        alert("Idle for 3 seconds. You can call your api here");
    }

    function resetTimer() {
        clearTimeout(time);
        time = setTimeout(callApi, 3000); 
        // 5 minute = 60000 * 5;
        // 1000 milliseconds = 1 second
    }
};

window.onload = function() {
  inactivityTime(); 
}
</script>

and it is working as expected.

whereas the same i am using in angular project, angular code is also working but 1 small issue observed please see my angular code first:

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'project';
  time;

  ngOnInit() {  
    this.inactivityTime();  
    this.resetTimer();
  }

  inactivityTime() {
    document.onmousemove = this.resetTimer;
    document.onkeypress = this.resetTimer;
    document.onclick = this.resetTimer;
    document.onwheel = this.resetTimer;

  }

  resetTimer() {
    clearTimeout(this.time);
    this.time = setTimeout(() => {
      alert('Idle for 3 seconds. You can call your api here');
    }, 3000);
  }
}

the problem i am facing is - on page load even if am doing mouse move / key press, the alert is getting called. after that everything is working as expected. But on page load it is not working.

Requesting help here.

thank you!


Solution

  • The best approach is to use Angular HostListener decorator and bind it to document:

    export class AppComponent {
      time: number;
    
      ngOnInit() {  
        this.resetTimer();
      }
    
      @HostListener('document:mousemove')
      @HostListener('document:keypress')
      @HostListener('document:click')
      @HostListener('document:wheel')
      resetTimer() {
        clearTimeout(this.time);
        this.time = setTimeout(() => {
          alert('Idle for 3 seconds. You can call your api here');
        }, 3000);
      }
    }
    

    Here is solution in stackblitz