Create a debounce click directive for buttons in a TypeScript file

I'm facing an issue with implementing debounce click on a dynamically added button using TypeScript. I need help with the correct syntax to make it work.

    private _initActionsFooter(): void {
        this.actionsFooterService.add([
            {
                label: 'AMBUSH.SHARED.FOOTER.HISTORY',
                click: () =>
                    this.dialogService.open(DialogHistoryAmbushComponent, {
                        context: {ambush: this.ambush}
                    }),
                outline: true,
                position: 'left',
                class: ['mr-3']
            },
            {
                label: 'AMBUSH.SHARED.FOOTER.DOCUMENTS',
                click: () => {
                    this.router.navigate([
                        'appostamenti',
                        this.route.snapshot.data.ambush.id,
                        'documenti'
                    ]);
                },
                outline: true,
                position: 'left',
                class: ['ml-3']
            },
            {
                label: 'AMBUSH.SHARED.FOOTER.REFRESH',
                click : () => this._save,
                disabled:
                    this.accessChecker.isGranted('view', 'only-view-atc') ||
                    this.ambushTabsStoreService.allFormsInvalid$,
                position: 'center',
                icon: 'save-outline',
            }
        ]);
        if (this.ambush?.fixedCabinOverId) {
            this.service
                .getDetail(this.ambush.fixedCabinOverId)
                .pipe(
                    catchError(() => {
                        return of(null);
                    })
                )
                .subscribe((res: Ambush) => {
                    this.cancellationReason = res.cancellationReason.value;
                });
        }
    }

These are the buttons, specifically interested in utilizing the function for the button labeled 'AMBUSH.SHARED.FOOTER.REFRESH'

This is my directive file which has been made accessible throughout the application

import {
  Directive,
  EventEmitter,
  HostListener,
  OnInit,
  Output
} from '@angular/core';
import { Subject } from 'rxjs';
import { debounceTime } from 'rxjs/operators';

@Directive({
  selector: '[appDebounceClick]'
})
export class DebounceClickDirective implements OnInit {
  @Output() debounceClick = new EventEmitter();
  private clicks = new Subject();

  constructor() {}

  ngOnInit() {
    this.clicks
      .pipe(debounceTime(500))
      .subscribe(e => this.debounceClick.emit(e));
  }

  @HostListener('click', ['$event'])
  clickEvent(event) {
    event.preventDefault();
    event.stopPropagation();
    this.clicks.next(event);
  }
}

Answer №1

Discovering the simplicity of debounce...:) and no need for rxjs in your directive

Simply put, when you interact or move around, reset the timeout

But if there's a pause, let the timeout run to execute your function...

1- Save the timeout in a variable

let timeoutId: ReturnType<typeof setTimeout>

2- Reset or leave the timeout

@HostListener('click', ['$event'])
clickEvent(e) {
  e.preventDefault();
  // Clear the one second timeout every click
  clearTimeout(timeoutId)
  timeoutId = setTimeout(() => {
    // do what you need to
  }, 1000)

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

What are the pros and cons of defining `[defaultColor]="'violet'"` in Angular 2?

If you visit the advanced section of angular.io documentation, you will come across the following code snippet: <p [myHighlight]="color" [defaultColor]="'violet'"> Highlight me too! </p> It made me wonder, when binding to a consta ...

jQuery DataTable error: Attempted to set property 'destroy' on an undefined object

<script> $('#archiveTable').DataTable({}); </script> <table id="archiveTable" datatable="ng" class="table table-sm" style="color:black"> <!--some code--> </table> This is a snippet of HTML code Upon checking t ...

Problem encountered with ESLint when utilizing babel module-resolver in conjunction with TypeScript

Typescript is not making type inferences with resolved imports, but it does with relative imports. Any assistance would be greatly appreciated. https://i.sstatic.net/2pgHX.png When using the 'useTheme' function, an error is displayed: "U ...

Using ngClass with template literals to dynamically alter its value

Is there a way to dynamically change the classes applied to a div using variables in Angular? In this scenario, I am attempting to modify a class based on the value of a string variable called color by using string interpolation. However, this approach i ...

Svelte language switcher experiencing technical difficulties

Currently delving into Svelte 3, I embarked on a project intended to be shared on GitHub in English. However, I realized that some of my friends do not speak English. To accommodate different language preferences, I decided to create a language switcher. H ...

Steps to fix the postinstall error in Angular CLI

Can anyone lend a hand in resolving the following error? npm ERR! errno -4058 npm ERR! @angular/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2c4f40456c14021c021a">[email protected]</a> postinstall: `node ./bin/p ...

"Exploring the relationship between Typescript and Angular: transforming variables within different

Ever since I made the switch from JavaScript to TypeScript (Version 2.1.5), I have been facing an issue with the code that filters date selection. Despite my efforts, I haven't been able to find a good fix for it yet. Here are the two date-pickers: F ...

Step-by-step guide on incorporating HTML into a popover within Angular4

After successfully implementing a hover popover in Angular using PopoverModule from ngx-popover, I now need to modify the content inside the popover. My search led me to this example: <ng-template #popContent>Hello, <b& ...

Using React's `cloneElement` to make modifications to a child component while maintaining the reference within a functional component

In the past, I had references in my component while rendering, and it was functioning as expected: // props.children is ReactElement<HTMLDivElement>[] const [childRefs] = useState<RefObject<any>[]>(props.children.map(() => createRef()) ...

What is the correct way to effectively integrate react-hook-form with redux and typescript?

After tirelessly searching for a comprehensive guide that could demonstrate all these requirements in one example, I eventually resorted to brute force to make something functional. However, I am well aware that this approach is not the correct way to achi ...

Issue: ALERT found in ./src/styles.scss (./node_modules/raw-loader!./node_modules/postcss-loader/lib?

Hello to all my fellow developers! I've been diving into the Angular 6 project recently and things are going smoothly for the most part. However, I keep encountering a warning in the console after running the application with (ng serve). WARNING i ...

The source files are expected to be contained within the 'rootDir' directory, which is not located at 'c:/Users/hasit/Desktop/typescript/src'

Can someone assist me with separating the Src folder and public folder in my project? When I try to do it in the tsconfig.json file, I encounter this error: "'rootDir' is expected to contain all source files." I have followed instructions from a ...

The child user interface component is failing to respond to keypress events within the parent component in an Angular project

I am facing a challenge in adding a keyboard shortcut to open a nested child UI Tab component through a keypress event. However, the Child nested tab can only be loaded after the Parent component is loaded first. Below is the structure of the UI tree: |-- ...

What is the best way to monitor updates made to a function that utilizes firestore's onSnapShot method?

I am currently working with the following function: public GetExercisePosts(user: User): ExercisePost[] { const exercisePosts = new Array<ExercisePost>(); firebase.firestore().collection('exercise-posts').where('created-by&apo ...

What is the reason that property spreading is effective within Grid components but not in FormControl components?

Explore the sandbox environment here: https://codesandbox.io/s/agitated-ardinghelli-fnoj15?file=/src/temp4.tsx:0-1206. import { FormControl, FormControlProps, Grid, GridProps } from "@mui/material"; interface ICustomControlProps { gridProps?: ...

Difficulty with the value binding issue on input text produced by *NgFor

When using *ngFor in Angular to loop over an array and generate input text elements bound to the values in the array, I'm encountering some issues. The value is not binding correctly when a user inputs something into the text field. I attempted to ru ...

Examining Axios HttpService piping through a NestJS middleware in a unit test

A middleware function retrieves a JSON document from a microservice endpoint and appends it to the request. The good path test is successful, but I'm struggling to make the bad path test throw a ForbiddenException and stop it from invoking next(). W ...

Access data inside nested objects with specified data type

Imagine the code snippet below: type Parent = { children: Child[] } type Child = { label: string } const parent: Parent = { children: [ { label: 'label1' }, { label: 'label2' } ] } How can I use generics to ...

Ways to Manage Button State in Angular Application During Compilation

Within my Angular application, I need to ensure that buttons can be enabled and disabled during production. I'm looking for a way to prevent any input from being manipulated by browser tools. ...

Differing preferences for indentation styles can lead to conflicting prett

My eslint setup is as follows: { "env": { "es2020": true, "jest": true }, "extends": [ "eslint:recommended", "plugin:react/recommended", "plugin:import/recommended&q ...