automatic sign out due to inactivity in an Aurelia application

Here's a quick summary: How can I trigger a function inside a view-model from outside of it using Aurelia?

I want to automatically log out a user if they remain inactive for a certain amount of time without performing any actions. After reading through this GitHub issue, I created an inactivity-logout view and view-model, integrated them into my app.html file, and used the attached() function to start a timer that logs the user out when the time limit is reached.

While everything is functioning as expected, I encountered an issue that has left me feeling lost. How do I call the resetInactivityTimer() function from another class outside of the view-model? Is there a way to make a function publicly accessible within a class? For example, when a request is made to the server, I would like to invoke the resetInactivityTimer() function from my service class.

inactivity-logout.ts

import {Aurelia} from 'aurelia-framework';
import {Router} from 'aurelia-router';
import {inject} from 'aurelia-dependency-injection';

@inject(Aurelia, Router)
export class InactivityLogout {
    inactivityWarningDuration: number; 
    initialInactivityWarningDuration: number; 
    inactivityDuration: number; 
    inactivityIntervalHandle: any;

    constructor(aurelia, router) {
        // Constructor code here
    }

    attached() {
        this.queueInactivityTimer();
    }

    resetInactivityTimer(){
        // Function code here
    }

    queueInactivityTimer(){
        // Function code here
    }

    displayWarning(){
        // Function code here
    }

    logout(){
        // Function code here
    }
}

app.html

    <require from='./inactivity-logout.js'></require>
    <inactivity-logout></inactivity-logout>

search-service.ts

    performSearch(searchText: String) {

        /*
         * Code here to reset the inactivity timer
         */

        return this.httpClient.put("/api/Search", searchText)
           .then(response => {
               return response;
           });
    }

Answer №1

A recommended approach for handling global events is to implement the PubSub pattern using the aurelia-event-aggregator library.

import {Aurelia} from 'aurelia-framework';
import {Router} from 'aurelia-router';
import {inject} from 'aurelia-dependency-injection';
import {EventAggregator} from 'aurelia-event-aggregator';

@inject(Aurelia, Router, EventAggregator)
export class InactivityLogout {
    inactivityWarningDuration: number; // how long should the warning be up
    initialInactivityWarningDuration: number; // how long should the warning be up
    inactivityDuration: number; // how long before we warn them
    inactivityIntervalHandle: any;

    constructor(aurelia, router, ea) {
        this.aurelia = aurelia;
        this.router = router;
        this.initialInactivityWarningDuration = 5;
        this.inactivityWarningDuration = this.initialInactivityWarningDuration;
        this.inactivityDuration = 5;
        this.ea = ea;
        
        // subscribe
        this.sub = this.ea.subscribe(RefreshInactivity, msg => {
           console.log(msg.value);
        });

        // to unsubscribe somewhere
        // this.sub.dispose()
    }
...

export class RefreshInactivity {
  
  constructor(value) {
    this.value = value;
  }
  
}

Trigger an event within the application

 this.ea.publish(new RefreshInactivity('some value'));

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Troubleshooting: Why is my Angular Ionic Reactive Form not showing up on the

I'm currently experiencing an issue with my Angular/Ionic form, where the form controls are not displaying correctly on the web. My goal is to create a dynamic form that allows users to input the number of groups and students for each year. However, w ...

What is a mapped Record type in which each key K in Record<T, K> is determined by the value of T?

My previous question from three weeks ago has led to this extension: Set the keys of an interface to the possible values of a different interface? In summary, I have the following type definitions: interface SuccessStatus { type: 'success'; ...

The request body doesn't meet the interface requirements, but it does not trigger an error response

I created a specific interface called NewTransactionPayload to ensure that only objects of this type are accepted in the request body. Strangely, TypeScript does not show any errors when I host the application. Why is that? // Sample interfaces interface ...

Issue with Angular 2 Routing: Unable to find a matching route

Currently, I'm in the process of developing an Angular 2+ application that requires routing. One of the requirements is for the color scheme of the entire app to change based on a URL parameter input. In my app.module.ts file, I have the following co ...

Copying an array of objects in TypeScript

I have a set of objects as shown below defined in the interface: myArray: [{ id: number; item: string; checked: boolean; }] I'm attempting to duplicate the array using the statement provided here: let newArray = myArray.map(x => Object ...

Encountering a premature closure error, specifically the inability to set headers after they have already been sent to the client, when trying to stream video

I am in the process of constructing a video streaming web server with Nestjs. I have diligently followed the steps outlined in the Nest documentation. Unfortunately, I encountered some errors... MY file.controller.ts import { Controller ...

What is the best way to show the character count for every input in an Angular application?

In my app component, I have two input fields. I want to display the character count and max character limit for each input field dynamically as users type or blur on the input field. To achieve this, I created a component that shows and hides the characte ...

The waitForAngularEnable function is failing to work properly as it is throwing a ScriptTimeoutError, indicating that the result was not received within

My journey begins on an Angular starting page. Clicking a button takes me to a login page that is non-angular. Once logged in, the rest of the pages are angular. I am utilizing async/await. I attempted including waitForAngularEnable(true) in onPrepare b ...

What is the process of mapping an object from a JSON file to a different object?

Displayed below is my json file { "data": [ { "firstName": "Tom", "lastName": "Yoda", "type": "guest", "id": "0", "gender&quo ...

What is the method for extracting only TypeScript types from the threeJs package?

I am in the process of developing a front-end application using Webpack with threeJs functionality integrated. Previously, I would refrain from bundling threeJs to keep the size small by utilizing the threeJs UMD from a CDN link in my index.html file. Desp ...

What is the most efficient way to use map-reduce in TypeScript to filter a list based on the maximum value of an attribute?

Recently, I came across a list that looked something like this: let scores = [{name: "A", skills: 50, result: 80}, {name: "B", skills: 40, result: 90}, {name: "C", skills: 60, result: 60}, {name: "D", skills: 60, ...

The art of chaining templates for Next.js metadata titles

I am currently working on a Next.js project with a multi-layered file organization, aiming to have each layout level contribute to the title prefix in a recursive manner. The end goal is to have the final title be a combination of all layout titles leading ...

Problems encountered with iframe-resizer in Next.js: Notification of GPLv3 License and Error message indicating "iFrame not responding"

My project in Next.js 14 involves creating a testimonial feature with testimonials displayed through an iframe. The aim is to generate an iframe tag (and potentially necessary script tags) that, when inserted into any website's HTML, allows users to v ...

Broaden your interfaces by implementing multiple interfaces with Zod

Utilizing typescript, I am able to incorporate multiple interfaces interface Name { name: string } interface Age { age: number } interface People extends Name, Age { height: number } Is there a similar way to achieve this with Zod? What I attempted ...

Cease the generation of dynamically produced sounds

I am encountering an issue in Angular where I am unable to stop playing an audio from a service. Below is my play() method: play(item: string): void { const audio = new Audio(); audio.src = item; audio.load(); audio.play(); } In order to stop all ...

Modifying a property in a nested layout through a page in Next.js 13

Currently, I am facing a challenge in updating the page title within a nested layout structure. app/docs/layout.tsx: export const DocsLayout = ({children}:{children: React.ReactNode}) => { return ( <> <header> ...

Form Style Components

I am currently using a form that contains material-ui components. Instead of relying on inline styles for the width property, I want to use css-in-js instead. I have previous experience with styled-components but there seems to be no form element available ...

Troubleshooting an angular problem with setting up a dynamic slideshow

I am currently working on building a slideshow using plain HTML, CSS, and JavaScript. I referred to the following example for guidance: https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_slideshow_auto However, despite implementing the code prov ...

Issues with Typescript when Adding Objects to an Array in a Function

In my Angular 2 application, I am encountering a problem when trying to add new items to an array. The issue appears to be related to Typescript types, although I'm not entirely certain. Here is the current structure of the array I am attempting to mo ...

Discovering an array containing a specific value and transforming it to another array in Angular 8

I have an array called this.data which contains a list of platforms. Each platform has its own set of section lists, where a section list consists of values like sectionName, sectionid, and sectionVal. Now, my goal is to replace the old sectionList with a ...