Update the boolean in the main Angular 'thread' async/await

195 Views Asked by At

I have the following async method. I use a loader in order to update the user interface, visibility of which is based on the isExporting flag.

public async copyToClipboard(element: HTMLDivElement): Promise<void> {

  this.isExporting = true; // <<<<<<<<<<<<<<<<<<<<<< HERE

  const data = await html2canvas(element, { scale: 1.5 }).then((canvas) => {
    canvas.toBlob((blob) => {
      const item = new ClipboardItem({ 'image/png': blob! });
      navigator.clipboard.write([item]).then((res) => {

        this.isExporting = false; // <<<<<<<<<<<<<<<<<<<<<< HERE

        this.notyfService.instance.success({
          message: this.translateService.instant('message.export.success'),
          duration: 2000
        });
      });
    });
  });
}

Then I have

<button [disabled]="isExporting" (click)="copyToClipboard(container!)">
    <kendo-loader *ngIf="isExporting"> </kendo-loader>
</button>

Even if isExporting is set to false before the NotifyService message, I get first of all the service message popup after the clipboard is updated, and only several seconds after the message the loader disappears - isExporting is updated in the main 'thread'.

Is there a way to notify the main 'thread' that isExporting is updated immediately?

1

There are 1 best solutions below

0
On

Following the Mike S. suggestion, I have updated the component like this:

constructor(
  private notyfService: NotyfService,
  private cd: ChangeDetectorRef,
) {
}


public async copyToClipboard(element: HTMLDivElement): Promise<void> {

  this.isExporting = true;
  this.cd.detectChanges();

  const data = await html2canvas(element).then((canvas) => {
    canvas.toBlob((blob) => {
      const item = new ClipboardItem({ 'image/png': blob! });
      navigator.clipboard.write([item]).then((res) => {
        this.notyfService.instance.success({
          message: 'message.export.success',
          duration: 2000
        });

        this.isExporting = false;
        this.cd.detectChanges();
      });
    });
  });
}

Now the loader is updated OK after the treatment, however I still have a delay of 3 seconds before it starts to spin, probably because isExporting=true is not detected immediately, even if I use detectChanges.