0

I've built a button component where one of its possible Inputs is the click handler. The problem is that the function that is passed to this handler is not in the correct context, when attempting to call the service that is injected into the parent component.

Parent Component Template

<app-vv-button
  [buttonText]="'Click me'"
  [type]="'primary'"
  [isLoading]="isLoading"
  [handler]="doFoo"></app-vv-button>

Child Component Template

<button class="btn btn--{{type}}" (click)="handler()">
  <span *ngIf="!isLoading">{{buttonText}}</span>
  <div class="loader" *ngIf="isLoading">Loading...</div>
</button>

Handler Function

public async doFoo() {
  this.isLoading = true;
  await this.barService.someFunction();
  this.isLoading = false;
}

Error:

ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'someFunction' of undefined
TypeError: Cannot read property 'someFunction' of undefined
at VvButtonComponent.eval (VM380 app.component.ts:61)

Stackblitz with the problem in question

CodePrimate
  • 6,646
  • 13
  • 48
  • 86
  • 1
    Try defining the callback as an arrow function: `doFoo = async () => { ... }` (as shown in [this stackblitz](https://stackblitz.com/edit/angular-7e4jwf?file=src/app/app.component.ts)). – ConnorsFan Mar 20 '20 at 19:57
  • 1
    By the way, I would suggest implementing the click handling with [Angular event binding](https://angular.io/guide/component-interaction#parent-listens-for-child-event), using `@Output()` to emit the event. That way, you would not have to declare the event handler as an arrow function. – ConnorsFan Mar 20 '20 at 20:07

0 Answers0