Implementing an Idle User Detector in Angular — without external libraries.

Mariodante
3 min readNov 14, 2023

--

Angular random image :P

Introduction

In many web applications, it’s crucial to know when a user is no longer active. This could be for security reasons, resource management, or to improve user experience. In this article, we will explore how to detect user inactivity on an Angular application using a custom service. This service will allow us to initiate a countdown after a period of inactivity and even notify the system when the user becomes idle.

The basic idea behind the service is to listen for user activity events, such as mouse movements, and start a countdown timer when no activity is detected. If the user becomes active again before the timer reaches zero, the countdown is reset. If the timer reaches zero, a logout action is triggered. Finally (and only for explanations reasons), you can reset the countdown using a ’reset’ button and ‘the magic’ will start to happen.

Important note: in this time, I want to explain this idea without external libraries, like to ng-idle.

Creating the service — IdleUserService

The IdleUserService will be responsible for detecting user inactivity and initiating a countdown. We will use native JavaScript event listeners to detect user activity on the viewport/page. If there is no activity for a specified time, we'll start a countdown, and if the countdown reaches zero, we'll conclude that the user is idle.

Here is the code for our service:

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

export enum IdleUserTimes {
IdleTime = 3000,
CountdownTime = 5000
}

@Injectable({
providedIn: 'root'
})
export class IdleUserService {
private timeoutId: any;
private countdownId: any;
private countdownValue: number;

userInactive: Subject<boolean> = new Subject();

constructor() {
this.reset();
this.initListener();
}

initListener() {
window.addEventListener('mousemove', () => this.reset());
window.addEventListener('click', () => this.reset());
window.addEventListener('keypress', () => this.reset());
window.addEventListener('DOMMouseScroll', () => this.reset());
window.addEventListener('mousewheel', () => this.reset());
window.addEventListener('touchmove', () => this.reset());
window.addEventListener('MSPointerMove', () => this.reset());
}

reset() {
clearTimeout(this.timeoutId);
clearTimeout(this.countdownId);
this.startIdleTimer();
}

startIdleTimer() {
this.timeoutId = setTimeout(() => {
console.log('Inactivity detected');
this.startCountdown();
}, IdleUserTimes.IdleTime);
}

startCountdown() {
this.countdownValue = IdleUserTimes.CountdownTime / 1000;
this.countdownId = setInterval(() => {
this.countdownValue--;
console.log('You will logout in:', this.countdownValue, 'seconds');
if (this.countdownValue <= 0) {
clearInterval(this.countdownId);
console.log('User idle');
this.userInactive.next(true);
}
}, 1000);
}
}

Implementing the Service in a Component

Now that we have our IdleUserService, let's use it in app.component.ts. We'll subscribe to the userInactive event of IdleUserService and, when the user becomes idle, we'll show a message and a button to reset the idle state.

import { Component, OnInit } from '@angular/core';
import { IdleUserService } from './idle-user.service';

@Component({
selector: 'app-root',
template: `
<div *ngIf="isUserIdle">
User is idle
<button (click)="reset()">Reset</button>
</div>
`,
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
isUserIdle: boolean = false;

constructor(private idleUserService: IdleUserService) {}

ngOnInit() {
this.idleUserService.userInactive.subscribe(isIdle => this.isUserIdle = isIdle);
}

reset() {
console.log('Reset idle timer');
this.isUserIdle = false;
this.idleUserService.reset();
}
}

Conclusion

By creating a custom service and using native JavaScript event listeners, we can efficiently detect user inactivity in an Angular application. This approach is highly customizable and can be adapted to suit various requirements like different idle times, different user activity events, etc. With this foundation, you can build more complex logic, like automatically logging out idle users or saving their work to avoid data loss.

By using this service, you can create more engaging and interactive web applications that respond to user activity in real-time.

Remember, the code shared in this article is just a basic implementation. Depending on your application, you may need to modify the code to suit your needs.

https://github.com/mariodantemariani/angular-userIdle-libraryFree

Thanks for your attention!

--

--

Responses (2)