angularangular-forms

How to track if Angular patchValue is already finished?


At the beginning of the application, i get server data and patch it to my form. Afterwards i would like to mark my form as pristine, so i can disable the submit button until user changes something. The problem is that patching takes so much time that i cant set my form as pristine. Only with setTimeout i can accomplish that which is a terrible solution. Any ideas how could i track if the patching is over or any alternative solution ? Thanks !

here i m trying to patch and than mark as pristine :

private _loadFormData() {
    if (this.detail) {
      this.caseOverviewForm?.patchValue(this.detail);
      this._loadDynamicFormOptions();
      setTimeout(() => this.caseOverviewForm.markAsPristine(),3000)
    }
  }

UPDATE : carried the setTimeout here, works a bit faster

 private _loadDynamicFormOptions(): void {
        this.categoryList$ = this.service
          .getCategoryList(this._optionPayload())
          .pipe(mapAndPatch(this.caseOverviewForm, FormFields.category, this.detail.id!));
    
        this.subCategoryList$ =
          this._updateSubDropDownList(FormFields.category, FormFields.subCategory, OptionsType.caseCategory)?.pipe(
            mapAndPatch(this.caseOverviewForm, FormFields.subCategory, this.detail.id!),
          ) ?? of([]);
        setTimeout(() => this.caseOverviewForm.markAsPristine())
      }

Here trying to disable submit button

<t-button
      [tooltipConfig]="tooltipConfig"
      [disabled]="caseOverviewForm.invalid || caseOverviewForm.pristine"
      [type]="buttonTypes.POSITIVE"
      [size]="buttonSizes.LARGE"
      (click)="submitChanges()"
    ></t-button>

Solution

  • You have some other asynchronous actions which mark the form as dirty again. To get the right timing, you can use combineLatest:

    private _loadDynamicFormOptions(): void {
      this.categoryList$ = this.service
        .getCategoryList(this._optionPayload())
        .pipe(mapAndPatch(this.caseOverviewForm, FormFields.category, this.detail.id!));
        
      this.subCategoryList$ =
        this._updateSubDropDownList(FormFields.category, FormFields.subCategory, OptionsType.caseCategory)?.pipe(
          mapAndPatch(this.caseOverviewForm, FormFields.subCategory, this.detail.id!),
        ) ?? of([]);
      
      combineLatest(this.categoryList$, this.subCategoryList$)
        .pipe(take(1))
        .subscribe(() => this.caseOverviewForm.markAsPristine());
    }