{"id":13497526,"url":"https://github.com/nigrosimone/ng-lock","last_synced_at":"2025-04-24T02:10:40.620Z","repository":{"id":85036988,"uuid":"356492580","full_name":"nigrosimone/ng-lock","owner":"nigrosimone","description":"Angular decorator for lock a function and user interface while a task running.","archived":false,"fork":false,"pushed_at":"2024-12-01T14:32:51.000Z","size":1557,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-11T19:38:03.388Z","etag":null,"topics":["angular","angular2","decorator","lock","locked-functions"],"latest_commit_sha":null,"homepage":"http://npmjs.com/package/ng-lock","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nigrosimone.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"open_collective":"simone-nigro"}},"created_at":"2021-04-10T06:25:45.000Z","updated_at":"2025-02-14T18:04:21.000Z","dependencies_parsed_at":null,"dependency_job_id":"db6cd894-d3cf-4572-a382-12c2e1d47a95","html_url":"https://github.com/nigrosimone/ng-lock","commit_stats":{"total_commits":141,"total_committers":1,"mean_commits":141.0,"dds":0.0,"last_synced_commit":"6433771a207fdac72f62ea6a610be05995e8f143"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nigrosimone%2Fng-lock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nigrosimone%2Fng-lock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nigrosimone%2Fng-lock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nigrosimone%2Fng-lock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nigrosimone","download_url":"https://codeload.github.com/nigrosimone/ng-lock/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250285650,"owners_count":21405296,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","angular2","decorator","lock","locked-functions"],"created_at":"2024-07-31T20:00:32.549Z","updated_at":"2025-04-24T02:10:40.603Z","avatar_url":"https://github.com/nigrosimone.png","language":"TypeScript","funding_links":["https://opencollective.com/simone-nigro","https://www.paypal.com/paypalme/snwp"],"categories":["Uncategorized","Third Party Components"],"sub_categories":["Uncategorized","DOM"],"readme":"# NgLock [![Build Status](https://travis-ci.com/nigrosimone/ng-lock.svg?branch=main)](https://travis-ci.com/nigrosimone/ng-lock) [![Coverage Status](https://coveralls.io/repos/github/nigrosimone/ng-lock/badge.svg?branch=main)](https://coveralls.io/github/nigrosimone/ng-lock?branch=main) [![NPM version](https://img.shields.io/npm/v/ng-lock.svg)](https://www.npmjs.com/package/ng-lock)\n\nAngular decorator for lock a function and user interface while a task running.\n\n## Description\n\nEver faced the issue where users click a button multiple times, causing chaos in your application? Meet `ng-lock`, the Angular library designed to save the day. It offers a straightforward way to lock functions and the user interface while a task is running.\n\n### Key Benefits:\n1. *Prevents Multiple Clicks*: Ensures a function executes only once until it completes, avoiding redundant operations;\n2. *User Interface Locking*: Disables UI elements to signal an ongoing process, enhancing user experience;\n3. *Easy Integration*: Simple decorators to lock and unlock functions, reducing boilerplate code.\n\nSee the [stackblitz demo](https://stackblitz.com/edit/demo-ng-lock?file=src%2Fapp%2Fapp.component.ts).\n\n## Get Started\n\n*Step 1*: install `ng-lock`\n\n```bash\nnpm i ng-lock\n```\n\n*Step 2*: Provide `NgLock` into your `bootstrapApplication`, eg.:\n\n```ts\nimport { bootstrapApplication } from '@angular/platform-browser';\nimport { AppComponent } from './app/app.component';\nimport { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';\nimport { provideNgLock } from 'ng-lock';\n\nbootstrapApplication(AppComponent, {\n  providers: [\n    provideNgLock(),\n    provideHttpClient(withInterceptorsFromDi())\n  ]\n});\n```\n\n*Step 3*: Decorate a function with `@ngLock()` decorator, eg.:\n\n```ts\nimport { Component, isDevMode, Signal, CommonModule } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { delay, Observable, of } from 'rxjs';\nimport {\n  ngLock,\n  ngUnlock,\n  withNgLockContext,\n  ngLockChanges,\n  NgLockDirective,\n  ngLockSignal,\n  ngLockObservable,\n} from 'ng-lock';\n\nconst sleep = (time: number) =\u003e new Promise(resolve =\u003e setTimeout(resolve, time));\nconst WAIT_TIME = 1500;\n\n@Component({\n  selector: 'app-root',\n  imports: [NgLockDirective, CommonModule],\n  template: `\n    \u003ch2\u003eExamples\u003c/h2\u003e\n    \u003cp\u003eSometime there is a need to lock the user interface while a task is running.\u003c/p\u003e\n    \u003chr /\u003e\n    Disable the button on click and enable when \u003cb\u003engUnlock\u003c/b\u003e is called\u003cbr\u003e\n    \u003cbutton (click)=\"onClick($event)\"\u003eClick me\u003c/button\u003e\n    \u003chr /\u003e\n    Disable the button on click and enable when \u003cb\u003eHTTP\u003c/b\u003e request is completed\u003cbr\u003e\n    \u003cbutton (click)=\"onHttpRequest($event)\"\u003eClick me\u003c/button\u003e\n    \u003chr /\u003e\n    Disable the button on click and enable when \u003cb\u003eObservable\u003c/b\u003e changes\u003cbr\u003e\n    \u003cbutton (click)=\"onObservable($event)\"\u003eClick me\u003c/button\u003e\n    \u003chr /\u003e\n    Disable the button on click and enable when \u003cb\u003ePromise\u003c/b\u003e is resolved\u003cbr\u003e\n    \u003cbutton (click)=\"onAsync($event)\"\u003eClick me\u003c/button\u003e\u003cbr\u003e\n    \u003cem\u003eSignal: {{ sigAsyncMethod() }}, Observable: {{ asyncMethod$ | async }}\u003c/em\u003e\n    \u003chr /\u003e\n    Disable the button on click and enable when \u003cb\u003eSubscription\u003c/b\u003e changes\u003cbr\u003e\n    \u003cbutton (click)=\"onSubscription($event)\"\u003eClick me\u003c/button\u003e\n    \u003chr /\u003e\n    Disable the button on click and enable when \u003cb\u003eunlockTimeout\u003c/b\u003e expire\u003cbr\u003e\n    \u003cbutton (click)=\"onTimeout($event)\"\u003eClick me\u003c/button\u003e\u003cbr\u003e\n    This input also depends on the lock state, see \u003cb\u003engLock\u003c/b\u003e directive \u003cbr\u003e\n    \u003cinput type=\"text\" [ngLock]=\"onTimeout\" value=\"test\"\u003e\n    \u003chr /\u003e\n  `,\n  styles: [`\n    button.ng-lock-locked {\n      pointer-events: none; // disable all event on element\n      border: 1px solid #999999;\n      background-color: #cccccc;\n      color: #666666;\n      user-select: none;\n    }\n  `]\n})\nexport class AppComponent {\n\n  // if you want more control over the lock status of a decorated method,\n  // you can get a Signal and/or an Observable of a given method,\n  // the status: when true is locked; when false is unlocked.\n  public sigAsyncMethod: Signal\u003cboolean\u003e = ngLockSignal(this.onAsync);\n  public asyncMethod$: Observable\u003cboolean\u003e = ngLockObservable(this.onAsync);\n  \n  constructor(private http: HttpClient) { }\n\n  /**\n   * @ngLock() apply \"ng-lock-locked\" class on first call and remove it on `ngUnlock(this.onClick)`\n   */\n  @ngLock({ debug: isDevMode() })\n  onClick(e: MouseEvent) {\n    setTimeout(() =\u003e {\n      ngUnlock(this.onClick);\n      console.log('onClick', 'done');\n    }, WAIT_TIME);\n  }\n\n  /**\n   * @ngLock() apply \"ng-lock-locked\" class on first call and remove it on HTTP response (@see withNgLockContext)\n   */\n  @ngLock({ debug: isDevMode() })\n  onHttpRequest(e: MouseEvent) {\n    this.http\n      .get('https://my-json-server.typicode.com/typicode/demo/db', {\n        context: withNgLockContext(this.onHttpRequest),\n      })\n      .subscribe((response) =\u003e console.log('onHttpRequest', response));\n  }\n\n  /**\n   * @ngLock() apply \"ng-lock-locked\" class on first call and remove it on observable changes (@see ngLockChanges)\n   */\n  @ngLock({ debug: isDevMode() })\n  onObservable(e: MouseEvent) {\n    of('done')\n      .pipe(delay(WAIT_TIME), ngLockChanges(this.onObservable))\n      .subscribe((response) =\u003e console.log('onObservable', response));\n  }\n\n  /**\n   * @ngLock() apply \"ng-lock-locked\" class on first call and remove it on promise resolve\n   */\n  @ngLock({ debug: isDevMode() })\n  async onAsync(e: MouseEvent) {\n    // async method or that return a Promise is handled, automatic unlock when resolve\n    await sleep(WAIT_TIME);\n    console.log('onAsync', 'done');\n  }\n\n  /**\n   * @ngLock() apply \"ng-lock-locked\" class on first call and remove on subscription changes\n   */\n  @ngLock({ debug: isDevMode() })\n  onSubscription(e: MouseEvent) {\n    // method that return a Subscription is handled, automatic unlock when changes\n    return of('done')\n      .pipe(delay(WAIT_TIME))\n      .subscribe((response) =\u003e console.log('onSubscription', response));\n  }\n\n  /**\n   * @ngLock() apply \"ng-lock-locked\" class on first call and remove it after unlockTimeout milliseconds\n   */\n  @ngLock({ debug: isDevMode(), unlockTimeout: WAIT_TIME })\n  onTimeout(e: MouseEvent) {\n    console.log('onTimeout', 'done');\n  }\n}\n```\n\n## NgLock options\n\nThere are some optional options can be injected into the `@ngLock()` decorator. This is an example with the default configuration:\n\n```ts\nimport { Component } from '@angular/core';\nimport { ngLock, ngUnlock } from 'ng-lock';\n\n@Component({\n  selector: 'app-root',\n  template: `\u003cbutton (click)=\"onClick($event)\"\u003eClick me!\u003c/button\u003e`,\n  styles: [`\n    button.ng-lock-locked {\n      pointer-events: none; // disable all event on element\n      border: 1px solid #999999;\n      background-color: #cccccc;\n      color: #666666;\n    }\n  `]\n})\nexport class AppComponent {\n\n  /**\n   * @ngLock() apply lock on method and \"ng-lock-locked\" class on first call and remove it on \"ngUnlock(this.onClick)\"\n   */\n  @ngLock({\n    maxCall: 1,\n    unlockTimeout: null,\n    lockElementFunction: ngLockElementByTargetEventArgument(),\n    lockClass: 'ng-lock-locked',\n    returnLastResultWhenLocked: false,\n    unlockOnPromiseResolve: true,\n    unlockOnObservableChanges: true,\n    debug: false\n  })\n  onClick(event: MouseEvent){\n    // ...simulate async long task\n    setTimeout(() =\u003e {\n      console.log(\"task executed\");\n      // unlock the method and remove \"ng-lock-locked\" class on the button\n      ngUnlock(this.onClick);\n    }, 3000);\n  }\n\n}\n```\n\nThe options are:\n\n| Option                       | Description                                                                                    | Default                                |\n| ---------------------------- | ---------------------------------------------------------------------------------------------- | -------------------------------------- |\n| *maxCall*                    | Max number of the calls beyond which the method is locked                                      | `1`                                    |\n| *unlockTimeout*              | Max time (in millisecond) to lock function                                                     | `null` _(no timeout)_                  |\n| *lockClass*                  | CSS class applied when the method is locked                                                    | `'ng-lock-locked'`                     |\n| *lockElementFunction*        | function for find the HTML element for apply the *lockClass*                                   | `ngLockElementByTargetEventArgument()` |\n| *returnLastResultWhenLocked* | if `true`, when the method is locked the last result is returned, otherwise return `undefined` | `false`                                |\n| *unlockOnPromiseResolve*     | if `true`, when a locked method return a Promise, the method is automatically unlock when the Promise is resolved| `true`                                |\n| *unlockOnObservableChanges*  | if `true`, when a locked method return a subscription, the method is automatically unlock when the observable changes| `true` \n| *debug*                      | if `true`, the decorator log into the console some info                                        | `false`                                |\n\n### Available lockElementFunction\n\nThe *lockElementFunction* is function used for find into the HTML the element for apply the *lockClass* (default class is `'ng-lock-locked'`).\n\n#### ngLockElementByQuerySelector(selector: string)\n\nUses the provided `selector` to find with `document.querySelector()` and apply the *lockClass* on the founded element. The `selector` is a `DOMString` containing a selector to match. Eg.:\n\n```ts\nimport { Component } from '@angular/core';\nimport { ngLock, ngUnlock } from 'ng-lock';\n\n@Component({\n  selector: 'app-root',\n  template: `\u003cbutton (click)=\"onClick()\" class=\"my-class\"\u003eClick me!\u003c/button\u003e`,\n  styles: [`\n    button.ng-lock-locked {\n      pointer-events: none; // disable all event on element\n      border: 1px solid #999999;\n      background-color: #cccccc;\n      color: #666666;\n    }\n  `]\n})\nexport class AppComponent {\n\n  /**\n   * @ngLock() apply lock on method and \"ng-lock-locked\" class on the html element with the class \"my-class\"\n   */\n  @ngLock({\n    lockElementFunction: ngLockElementByQuerySelector('.my-class')\n  })\n  onClick(){\n    // ...simulate async long task\n    setTimeout(() =\u003e {\n      console.log(\"task executed\");\n      // unlock the method and remove \"ng-lock-locked\" class on the button\n      ngUnlock(this.onClick);\n    }, 3000);\n  }\n\n}\n```\n\n#### ngLockElementByTargetEventArgument(argsIndex?: number)\n\nUses a function argument for apply the *lockClass*. If provided a `argsIndex` use the specific argument (index of the argument), otherwise search an argument with a target property (o currentTarget) that is a `HTMLElement`. Eg.:\n\n```ts\nimport { Component } from '@angular/core';\nimport { ngLock, ngUnlock } from 'ng-lock';\n\n@Component({\n  selector: 'app-root',\n  template: `\u003cbutton (click)=\"onClick(1, $event)\"\u003eClick me!\u003c/button\u003e`,\n  styles: [`\n    button.ng-lock-locked {\n      pointer-events: none; // disable all event on element\n      border: 1px solid #999999;\n      background-color: #cccccc;\n      color: #666666;\n    }\n  `]\n})\nexport class AppComponent {\n\n  /**\n   * @ngLock() apply lock on method and \"ng-lock-locked\" class on the html element provided into the target element of the second argument (index 1) of onClick() method\n   */\n  @ngLock({\n    lockElementFunction: ngLockElementByTargetEventArgument(1)\n  })\n  onClick(value: number, event: MouseEvent){\n    // ...simulate async long task\n    setTimeout(() =\u003e {\n      console.log(\"task executed\", value);\n      // unlock the method and remove \"ng-lock-locked\" class on the button\n      ngUnlock(this.onClick);\n    }, 3000);\n  }\n\n}\n```\n\n#### ngLockElementByComponentProperty(property: string)\n\nApply *lockClass* to a component property that must be a `HTMLElement` or element with Angular `nativeElement` (also a `HTMLElement`). Eg.:\n\n```ts\nimport { Component, ViewChild } from '@angular/core';\nimport { ngLock, ngUnlock } from 'ng-lock';\n\n@Component({\n  selector: 'app-root',\n  template: `\u003cbutton (click)=\"onClick()\" #button\u003eClick me!\u003c/button\u003e`,\n  styles: [`\n    button.ng-lock-locked {\n      pointer-events: none; // disable all event on element\n      border: 1px solid #999999;\n      background-color: #cccccc;\n      color: #666666;\n    }\n  `]\n})\nexport class AppComponent {\n\n  @ViewChild(\"button\") button: ElementRef\u003cHTMLElement\u003e;\n\n  /**\n   * @ngLock() apply lock on method and \"ng-lock-locked\" class on the html element provided into the \"button\" property of the component\n   */\n  @ngLock({\n    lockElementFunction: ngLockElementByComponentProperty('button')\n  })\n  onClick(){\n    // ...simulate async long task\n    setTimeout(() =\u003e {\n      console.log(\"task executed\");\n      // unlock the method and remove \"ng-lock-locked\" class on the button\n      ngUnlock(this.onClick);\n    }, 3000);\n  }\n\n}\n```\n\n#### Write a custom lockElementFunction\n\nYou can write a custom *lockElementFunction*. Eg.:\n\n```ts\nimport { Component } from '@angular/core';\nimport { ngLock, ngUnlock, NgLockElementFunction, NgLockElementFinder } from 'ng-lock';\n\nconst myLockElementFunction: NgLockElementFunction = (): NgLockElementFinder =\u003e {\n  /**\n   * @param self Is a component instance (in this example AppComponent).\n   * @param args Is a @ngLock() decorated function arguments (in this example onClick()).\n   */\n  return (self: any, args: any[]): Element =\u003e {\n    // Write your logic here ...\n  };\n};\n\n@Component({\n  selector: 'app-root',\n  template: `\u003cbutton (click)=\"onClick()\" #button\u003eClick me!\u003c/button\u003e`,\n  styles: [`\n    button.ng-lock-locked {\n      pointer-events: none; // disable all event on element\n      border: 1px solid #999999;\n      background-color: #cccccc;\n      color: #666666;\n    }\n  `]\n})\nexport class AppComponent {\n\n  @ngLock({\n    lockElementFunction: myLockElementFunction()\n  })\n  onClick(){\n    // ...simulate async long task\n    setTimeout(() =\u003e {\n      console.log(\"task executed\");\n      // unlock the method and remove \"ng-lock-locked\" class on the button\n      ngUnlock(this.onClick);\n    }, 3000);\n  }\n\n}\n```\n\n## Utils function\n\nUtils function exported by `ng-lock` library\n### ngLock(options?: NgLockOption): MethodDecorator\n\nLock the provided function. Usage as decorator eg.:\n\n```ts\n@ngLock()\nonClick(event: MouseEvent){\n  // ...\n}\n```\n\n### ngUnlock(methodToUnlock: NgLockFunction): void\n\nUnlock a locked function by `ngLock()` decorator. Usage, eg.:\n\n```ts\n@ngLock()\nonClick(event: MouseEvent){\n  // ...\n  ngUnlock(this.onClick);\n}\n```\n### ngIsLock(methodToCheck: NgLockFunction): boolean\n\nReturn `true` if the provided function is locked by `ngLock()` decorator. Usage, eg.:\n\n```ts\n@ngLock()\nonClick(event: MouseEvent){\n  // ...\n  console.log('onClick is locked?', ngIsLock(this.onClick) );\n}\n```\n\n### ngUnlockAll(component: any): void\n\nUnlock all locked functions by `ngLock()` decorator. Argument `component` is the component instance (`this`). Usage, eg.:\n\n```ts\n@ngLock()\nonClick(event: MouseEvent){\n  // ...\n  ngUnlockAll(this);\n}\n```\n\n### ngLockSignal(method: NgLockFunction): Signal\u003cboolean\u003e\n\nReturn a Signal for the given function on the lock status (locked/unlocked), eg.:\n\n```ts\npublic myMethodSignal: Signal\u003cboolean\u003e = ngLockSignal(this.myMethod);\n```\n\n### ngLockObservable(method: NgLockFunction): Observable\u003cboolean\u003e\n\nReturn an Observable for the given function on the lock status (locked/unlocked), eg.:\n\n```ts\npublic myMethod$: Observable\u003cboolean\u003e = ngLockObservable(this.myMethod);\n```\n\n### ngLockChanges(methodToUnlock: NgLockFunction): (source$: Observable\u003cT\u003e) =\u003e Observable\u003cT\u003e\n\nRxJS Operator that unlock the method when Observable changes, eg.:\n\n```ts\n@ngLock()\nonClick(event: MouseEvent) {\n  of(true).pipe(ngLockChanges(this.onClick)).subscription();\n}\n```\n\n### withNgLockContext(methodToUnlock: NgLockFunction, context: HttpContext = new HttpContext()): HttpContext\n\nReturn a HttpContext that unlock the method when HTTP respond, eg.:\n\n```ts\n@ngLock()\nonClick(event: MouseEvent) {\n  this.http.get('https://my-json-server.typicode.com/typicode/demo/db', {\n    context: withNgLockContext(this.onClick),\n  }).subscribe();\n}\n```\n\n### ngLock directive\n\nThe `ngLock` directive it's a Angular directive lock html element when a decorated method with `@ngLock` is running a task, eg.:\n\n```ts\nimport { Component } from '@angular/core';\nimport { ngLock, NgLockDirective } from 'ng-lock';\n\n@Component({\n  selector: 'app-root',\n  imports: [NgLockDirective],\n  template: `\n    \u003cinput [ngLock]=\"myMethod\" /\u003e\u003cbutton (click)=\"myMethod($event)\"\u003eSend\u003c/button\u003e\n  `\n})\nexport class AppComponent {\n  @ngLock()\n  myMethod(event: MouseEvent){\n    return new Promise(resolve =\u003e setTimeout(resolve, 5000));\n  }\n}\n```\n\n## Examples\n\nBelow there are some examples of use case.\n\n### Example: unlockTimeout\n\nExample of use with `unlockTimeout` option, eg.:\n\n```ts\nimport { Component } from '@angular/core';\nimport { ngLock, ngIsLock } from 'ng-lock';\n\n@Component({\n  selector: 'app-root',\n  template: `\n    \u003cbutton (click)=\"onClick($event)\"\u003eClick me!\u003c/button\u003e\n    \u003cbutton (click)=\"onCheck()\"\u003eCheck\u003c/button\u003e\n  `,\n  styles: [`\n    button.ng-lock-locked {\n      pointer-events: none; // disable all event on element\n      border: 1px solid #999999;\n      background-color: #cccccc;\n      color: #666666;\n    }\n  `]\n})\nexport class AppComponent {\n\n  /**\n   * @ngLock() apply lock on method and \"ng-lock-locked\" class on first call and remove it after 3 seconds\n   */\n  @ngLock({\n    unlockTimeout: 3000\n  })\n  onClick(event: MouseEvent){\n    console.log(\"task executed\");\n  }\n\n  onCheck(){\n    console.log('onClick lock state:', ngIsLock(this.onClick));\n  }\n}\n```\n### Example: maxCall\n\nExample of use with `maxCall` option, eg.:\n\n```ts\nimport { Component } from '@angular/core';\nimport { ngLock, ngIsLock, ngUnlock } from 'ng-lock';\n\n@Component({\n  selector: 'app-root',\n  template: `\n    \u003cbutton (click)=\"onClick($event)\"\u003eClick me!\u003c/button\u003e\n    \u003cbutton (click)=\"onCheck()\"\u003eCheck\u003c/button\u003e\n    \u003cbutton (click)=\"onUnlock()\"\u003eUnlock\u003c/button\u003e\n  `,\n  styles: [`\n    button.ng-lock-locked {\n      pointer-events: none; // disable all event on element\n      border: 1px solid #999999;\n      background-color: #cccccc;\n      color: #666666;\n    }\n  `]\n})\nexport class AppComponent {\n\n  /**\n   * @ngLock() apply lock on method and \"ng-lock-locked\" class after 3 call\n   */\n  @ngLock({\n    maxCall: 3\n  })\n  onClick(event: MouseEvent){\n    console.log(\"task executed\");\n  }\n\n  onCheck(){\n    console.log('onClick lock state:', ngIsLock(this.onClick));\n  }\n\n  onUnlock(){\n    ngUnlock(this.onClick);\n  }\n}\n```\n\n## Support\n\nThis is an open-source project. Star this [repository](https://github.com/nigrosimone/ng-lock), if you like it, or even [donate](https://www.paypal.com/paypalme/snwp). Thank you so much!\n\n## My other libraries\n\nI have published some other Angular libraries, take a look:\n\n - [NgSimpleState: Simple state management in Angular with only Services and RxJS](https://www.npmjs.com/package/ng-simple-state)\n - [NgHttpCaching: Cache for HTTP requests in Angular application](https://www.npmjs.com/package/ng-http-caching)\n - [NgGenericPipe: Generic pipe for Angular application for use a component method into component template.](https://www.npmjs.com/package/ng-generic-pipe)\n - [NgLet: Structural directive for sharing data as local variable into html component template](https://www.npmjs.com/package/ng-let)\n - [NgForTrackByProperty: Angular global trackBy property directive with strict type checking](https://www.npmjs.com/package/ng-for-track-by-property)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnigrosimone%2Fng-lock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnigrosimone%2Fng-lock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnigrosimone%2Fng-lock/lists"}