skip to Main Content

I want to have a spinner while I am waiting for my API to complete, but here I have a problem. When I press the button onSave correctly I saw the spinner, but after my API has completed my spinner is still here. Why is it not working? I want to close the spinner after complete.

public onSave() {
  this.isSaving = true
    this.formService.entityForm.markAsPristine();
    this.visaSubmitHandler.execute({ application: this.formService.entityForm.value }).subscribe({
        next: (response: IApplicationCreateResponse) => {
            this.stateRehydrationService.clearStateKey(this.formService.key);
            this.visaSuccessHandler.execute({ application: response.entity });
        },
        error: (response: IApplicationCreateResponse) => {
            this.formService.entityForm.markAsDirty();
            try {
                for (const error of response.errors) {
                    const propertyName = `${error.propertyName[0].toLowerCase()}${error.propertyName.slice(1)}`
                    const control = this.formService.entityForm.get(propertyName) as AbstractControl;
                    setErrors({ serverError: error.message }, control);
                }

                this.bottomSheet.open(DisplayErrorsComponent, { data: response.errors.map(e => e.message) });
            } catch (e) {
                console.error(e);
            }
        },
        complete: () => {
          this.isSaving = false
        }
    })
}
<div class="overlay" *ngIf="isSaving">
    <div class="spinner-container">
      <mat-spinner></mat-spinner>
    </div>
  </div>

2

Answers


  1. Here’s an updated version of your code:

    import { ChangeDetectorRef } from '@angular/core';
    
    // ...
    
    constructor(private cdr: ChangeDetectorRef) {}
    
    public onSave() {
      this.isSaving = true;
    
      this.formService.entityForm.markAsPristine();
      
      this.visaSubmitHandler.execute({ application: this.formService.entityForm.value }).subscribe({
        next: (response: IApplicationCreateResponse) => {
          this.stateRehydrationService.clearStateKey(this.formService.key);
          this.visaSuccessHandler.execute({ application: response.entity });
        },
        error: (response: IApplicationCreateResponse) => {
          this.formService.entityForm.markAsDirty();
          try {
            for (const error of response.errors) {
              const propertyName = `${error.propertyName[0].toLowerCase()}${error.propertyName.slice(1)}`
              const control = this.formService.entityForm.get(propertyName) as AbstractControl;
              setErrors({ serverError: error.message }, control);
            }
    
            this.bottomSheet.open(DisplayErrorsComponent, { data: response.errors.map(e => e.message) });
          } catch (e) {
            console.error(e);
          }
        },
        complete: () => {
          this.isSaving = false;
          this.cdr.detectChanges(); // Trigger change detection
        }
      });
    }
    import { ChangeDetectorRef } from '@angular/core';
    
    // ...
    
    constructor(private cdr: ChangeDetectorRef) {}
    
    public onSave() {
      this.isSaving = true;
    
      this.formService.entityForm.markAsPristine();
      
      this.visaSubmitHandler.execute({ application: this.formService.entityForm.value }).subscribe({
        next: (response: IApplicationCreateResponse) => {
          this.stateRehydrationService.clearStateKey(this.formService.key);
          this.visaSuccessHandler.execute({ application: response.entity });
        },
        error: (response: IApplicationCreateResponse) => {
          this.formService.entityForm.markAsDirty();
          try {
            for (const error of response.errors) {
              const propertyName = `${error.propertyName[0].toLowerCase()}${error.propertyName.slice(1)}`
              const control = this.formService.entityForm.get(propertyName) as AbstractControl;
              setErrors({ serverError: error.message }, control);
            }
    
            this.bottomSheet.open(DisplayErrorsComponent, { data: response.errors.map(e => e.message) });
          } catch (e) {
            console.error(e);
          }
        },
        complete: () => {
          this.isSaving = false;
          this.cdr.detectChanges(); // Trigger change detection
        }
      });
    }
    
    Login or Signup to reply.
  2. The simple answer is that in your template the variable isSaving still has the value true.

    Therefore,

    • either the change detection is disabled by OnPush (in this case you do manual changeDetectorRef.markForCheck() right after this.isSaving = false;)
    • or the observable this.visaSubmitHandler.execute does not complete (in this case you can do this.isSaving = false; in your next: block or ensure that your observable is closed.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search