Prevent the element attribute from being enabled before the onclick function is triggered

I am attempting to implement a feature in Angular that prevents double clicking on buttons using directives.

Below is the pertinent code snippet from my template:

<button (click)="onClickFunction()" appPreventDoubleClick>Add</button>

And here is the directive I have defined for this purpose:

@Directive({
  selector: "[appPreventDoubleClick]"
})
export class PreventDoubleClickDirective {
  count: number = 0;
  constructor() {}

  @HostListener("click", ["$event"])
  click(event) {
    ++this.count;
    if (this.count > 1) {
      console.log("disabling");
      event.srcElement.setAttribute("disabled",true);
      setTimeout(() => {
        event.srcElement.removeAttribute("disabled");
        this.count = 0;
      }, 1000);
    }
  }
}

The main goal here is to disable a button if it is clicked twice and then re-enable it after one second to prevent onClickFunction() from being triggered while the button is disabled. However, I am facing an issue where even though the @HostListener click() function runs before onClickFunction(), the latter still executes. How can I resolve this? Any assistance would be greatly appreciated.

Edit: In response to a comment, I must note that initially, I tried the following approach:

@HostListener("click", ["$event"])
click(event) {
  event.srcElement.setAttribute("disabled", true);
  setTimeout(() => {
    event.srcElement.removeAttribute("disabled");
  }, 1000);
}

However, this method has a drawback as the button may get disabled before the first invocation of the function. I am seeking a more universal solution that works consistently across different scenarios. Could someone explain why this inconsistency happens and provide suggestions for rectifying it? Your input is highly valued. Thank you in advance.

Answer №1

Great news! I've managed to solve the issue at hand. Below you'll find my directive with the updated code implementation.

@Directive({
  selector: "[appPreventDoubleClick]"
})
export class PreventDoubleClickDirective {
  constructor() {}

  @HostListener("click", ["$event"])
  click(event) {
    setTimeout(() => {
      event.srcElement.setAttribute("disabled", true);
    }, 0);
    setTimeout(() => {
      event.srcElement.removeAttribute("disabled");
    }, 1000);
  }
}

I don't have a full explanation for why this solution works, but hopefully some of you can shed some light on it.

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

Synchronization problem encountered in an Angular app involving playwright

Currently, I am working on automating a process where the service queries the database and displays the data on the user interface. However, the rendering takes a considerable amount of time, around 3 minutes. Despite using Playwright for automation, it do ...

Using Typescript for AngularJS bindings with ng.IComponentController

Currently, I am utilizing webpack alongside Babel and Typescript Presently, the controller in question is as follows: // HelloWorldController.ts class HelloWorldController implements ng.IComponentController { constructor(private $scope: ng.IScope) { } ...

Encountering a 405 error when making an OpenAI API call with next.js, typescript, and tailwind CSS

I encountered a 405 error indicating that the method request is not allowed. I am attempting to trigger an API route call upon clicking a button, which then connects to the OpenAI API. Unsure of my mistake here, any guidance would be highly appreciated. E ...

Filtering out specific properties from an element within a JavaScript forEach loop

const findBloodType = bloodCodeArray.find(bloodCode => bloodCode.code.toUpperCase() === bloodType.toUpperCase()).code; In my Angular code, I am trying to retrieve just the 'code' property of the 'bloodCode' element using a callback ...

What is the function of the Angular dependency injection mechanism?

I'm trying to grasp the inner workings of Angular/NestJs dependency injection. It's intriguing how the type of parameters gets lost when a Typescript class is constructed. For example: type Dependency1 = {}; type Dependency2 = {}; class X { ...

The "isActive" value does not share any properties with the type 'Properties<string | number, string & {}>'. This issue was encountered while using React with TypeScript

I'm attempting to include the isActive parameter inside NavLink of react-router-dom version 5, but I'm encountering two errors. The type '({ isActive }: { isActive: any; }) => { color: string; background: string; }' does not have an ...

Fixed headers remain in place as you scroll horizontally on a single table

Within my system, I have organized two tables: table one and table 2 are stacked on top of each other. I've managed to freeze the column headers so that they are displayed vertically, remaining static as users scroll horizontally. To achieve this effe ...

promise not being returned by service method

In my Angular 8 application, I am facing an issue where the promise call does not return an exception when it occurs. Can someone help me understand how to make getRepApprovedName return a promise? When I use 'return http.get', I encounter a synt ...

What is the correct way to write SVG markup within SVG tags in a React and NextJS environment?

I currently have a Svg component set up like this interface SvgIconProps { children: React.ReactNode; strokeWidth?: number; width?: number; height?: number; className?: string; } export const SvgIcon = ({ children, strokeWidth = 1, width = ...

Transfer highlighted checkboxes between two containers. Any deselected checkboxes in the second container should also be removed from the initial container

I have successfully populated the necessary checkboxes within a single div element. Furthermore, I have been able to save the selected checkboxes to an object. I am interested in learning how to display this object (checkboxes) in another div. Additional ...

Customizing MUI Themes with TypeScript: How do I inform TypeScript that the theme is provided by the provider?

Below is a modified demo code snippet extracted from Material UI documentation: function ThemeUsage() { const theme = { palette: { primary: { main: "#000", }, }, } as const; type DefaultThemeType = { theme: type ...

Generate app registration in Azure Active Directory by automatically setting up credentials using the administrator's username and password

I am encountering a challenge that I currently cannot comprehend. In my growing list of over 100 different tenants, I aim to automatically create an app registration for each tenant with specific API permissions granted. Upon my initial login to an Azure ...

How can Material UI React handle long strings in menu text wrapping for both mobile and desktop devices?

Is there a way to ensure that long strings in an MUI Select component do not exceed the width and get cut off on mobile devices? How can I add a text-wrap or similar feature? Desktop: https://i.sstatic.net/lo8zM.png Mobile: https://i.sstatic.net/8xoW6. ...

Reset the angular child component trigger by its parent component, which is a modal popup

I'm facing an issue with my Angular application where I have a child component within a parent modal window implemented using ngx-smart-modal. When I close the modal using the method: this.ngxSmartModalService.getModal('ModalNameComponent') ...

Transforming Javascript into Typescript with node modules in Visual Studio 2015

After developing a JavaScript web app using npm and webpack, I successfully converted all the .js files to .ts using the PowerShell command found here. Now, I am looking to transition to a VS2015 TypeScript project but struggling to find guidance on how ...

What is the purpose of using both forRoot() and forChild() in the RouterModule

What is the purpose of Angular RouterModule using forRoot() and forChild() methods? I recently learned about the forRoot pattern and how it protects provider singletons from being imported multiple times (https://angular.io/guide/singleton-services#the-fo ...

Troubleshooting issue with Angular2 Dart ngFor not refreshing view with WebSockets data stream

Recently, I've been facing an issue with an Angular2 component. Whenever I use websockets, the view fails to update properly. Interestingly, everything runs smoothly when I make http requests, but I really need to ensure that the data in the view stay ...

"Exploring the process of unsubscribing or disposing of an interval observable based on a certain condition in Angular2 or

I am embarking on the journey into Rx and reactive programming, facing a situation that requires me to continuously monitor a hardware's status by sending a POST request to its REST API every 500ms. The goal is to stop the interval observable once the ...

The full-screen material dialog's Y-scrollbar is overlapping with the page's Y-scrollbar

I'm currently working on a material dialog that takes up the full screen. The content of the dialog is larger than the screen height, resulting in a vertical scrollbar within the dialog. However, the overall page is also taller than the screen height ...

Exploring the implementation of binding a dynamic title using interpolation within a Kendo TabStrip component in an Angular 2

I have been attempting to bind interpolated titles into a Kendo TabStrip for Angular 2, but my code doesn't seem to be functioning correctly. When using hardcoded data without interpolation, everything works fine. However, when trying to incorporate ...