Angular component aware of event emitter's result

I have a generic button component:

@Component({
  selector: "debounced-submit-button"
  template: `
    <button (click)="debounceClick.emit()" [disabled]="disabled">
      <ng-content></ng-content>
    </button>
  `})
export class DebouncedSubmitButton {
  @Input() disabled: boolean = false;
  @Output() debounceClick = new EventEmitter();
}

And I use it like:

@Component({
  selector: "example-component",
  template: `
    <debounced-submit-button (debounceClick)="makeBackendCall()" disabled="loading">
    </debouncedSubmitButton>
  `})
export class ExampleComponent {
  loading = false;
  makeBackendCall(): Promise<any> {
    this.loading = true;
    return apiService.makeCall()
      .then(result => useResult(result))
      .finally(() => this.loading = false);
  }
}

So you can't click on the button again while the HTTP call is in progress. However, this requires me include a lot of boilerplate call to track "loading" wherever I have a button.

Is there any way to communicate back the results of the (debounce-click) event to the debounced-submit-button, so I can centrally locate my disabling code? Like, ideally, I just want

<debounced-submit-button (debounce-click)="makeBackendCall()">

and have the component be something like

@Component({
  selector: "debounced-submit-button"
  template: `
    <button (click)="onClick($event)" [disabled]="disabled">
      <ng-content></ng-content>
    </button>
  `})
export class DebouncedSubmitButton {
  disabled: boolean = false;
  @Output() debounceClick = new EventEmitter();

  onClick() {
    this.disabled = true;
    // I don't think this works, but I want the return value of the callback function
    httpCall = debounceClick.emit();
    httpCall.finally(() => this.disabled = false);
  }
}

Like, obviously this doesn't work, because the debounceClick event emitter could be subscribed to by multiple listeners, or no listeners. I'm just looking for a less-boilerplate-y way to communicate to the DebouncedSubmitButton that the API call is done, and the user should be able to interact with it again. Is there a way to do this?



Comments

Popular posts from this blog

Spring Elasticsearch Operations

Network Error and Timeout on Authorize.net JS

Object oriented programming concepts (OOPs)