1

I have a reactive form that on cancel has to set again the initial form values into the formGroup.

import { Map } from "immutable";

@Input() data: any;

public ngOnInit() {
    if (this.data && this.data.controls) {
        this.group = this.fb.group({
            isActive: [this.data.isActive],
            items: this.fb.array(this.buildFormArray(this.data.controlPerformers)),
            });

        // Deep copy of the formGroup with ImmutableJs
        this.originalFormData = Map(this.group).toJS();
    }
}

 public buildFormArray(controllers: IControlPerformer[]) {
    return controllers.map((ctlr) => {
        return this.fb.group({
            user: [ctrl.userData],
            ctrlName: [ctlr.name, Validators.required],
            date: [moment(ctlr.date).toDate(), Validators.required],
        });
    });
}

public cancel() {
  const existingItems = this.group.get("items") as FormArray;
  while (existingItems.length) {
            existingItems.removeAt(0);
        }

        // Here the error when trying to set the FormArray value
        this.group.setValue(this.originalFormData.value);  
   }

The error message:

There are no form controls registered with this array yet. If you're using ngModel, you may want to check next tick (e.g. use setTimeout).

This question had the same issue, but I could not fix it in my case.

UPDATE - Below The value of formGroup. It looks good and properly initialized.

{
 "isActive": true,
 "items": [
  {
   "user": "Walter",
   "ctrlName": "Orders",
   "date": "2018-03-18T23:00:00.000Z"
  }
}
Francesco
  • 7,749
  • 6
  • 51
  • 88

1 Answers1

6

If you remove items from the form array, then you need to add them anew, since setValue or patchValue functions do not create form control if it is missing, but rather only set/modify existing form control value. So, just add new controls to empty FormArray:

public cancel() {
  const existingItems = this.group.get("items") as FormArray;
  while (existingItems.length) {
    existingItems.removeAt(0);
  }

  // Even adding a new FormGroup to the array, the exception remains.
  // existingItems.push(this.fb.group({})););

  // Here the error when trying to set the FormArray value
  this.group.patchValue(this.originalFormData.value);
  this.originalFormData.value.items.forEach(item => {
    existingItems.push(this.fb.group(item)); 
  });
}

STACKBLITZ: https://stackblitz.com/edit/angular-rsglab?file=app%2Fhello.component.ts

Andriy
  • 12,868
  • 3
  • 39
  • 46
  • I am facing a issue while push into formarray I need to set error if have for that form array control how could do that – Mohamed Sahir Sep 14 '20 at 16:06
  • you can set error on any AbstractControl with `setErrors()` method (https://github.com/angular/angular/blob/593bd594e3419a2c834707e0f5d1dc86e1f94418/packages/forms/src/model.ts#L812), like `existingItems.setErrors({yourError: true})`. To get errors you can use `getError()` or examine `existingItems.errors` object – Andriy Sep 15 '20 at 05:29
  • I have set error on value changes but while creating a form array initially from server response i can able to set value but not able to do that for errors could you please look on it yow will get better clarity what i am asking https://stackoverflow.com/questions/63888311/how-can-we-set-errors-on-form-array-control-dynamically-on-initally-page-load – Mohamed Sahir Sep 15 '20 at 05:55