arraysangularangular-reactive-formsreact-final-form-arrays

FormArray does not print on my Reactive Form


I'm starting at Angular and I'm having a really hard time setting a FormArray inside my form. In summary what I did was:

Follow the codes:

.ts

let group = {}
    this.holidaysForm = new FormGroup(group);

    this.valForm = fb.group({
      dentistId: [null, Validators.required],
      initialHour: [null, Validators.required],
      endHour: [null, Validators.required],
      numberOfHolidays: [null],
      appointmentsInterval: [null, Validators.required],
      year: [null, Validators.required],
      workDays: this.buildDays(),
      holidays: this.buildHolidays()
    });

  buildDays() {
    const values = this.workDays.map(v => new FormControl(false));    
    return this.fb.array(values);
  }

  buildHolidays() {
    if (typeof this.valForm !== 'undefined') {
      let teste = Object.assign({}, this.holidaysForm.value);
      this.holidays = new Array();
      Object.values(teste).forEach((v) => {
        this.holidays.push(v);
      })
      console.log(this.holidays);
      const values = this.holidays.map((v)=> new FormControl(v));      
      return this.fb.array(values);
    }
  }

  dynamicForm(val) {
    if (val > 365) {
      val = 365;
      this.valForm.patchValue({
        numberOfHolidays: 365
      })
    }
    const val_plus_one = parseInt(val) + 1
    let i: number = val_plus_one;
    if (i < this.oldNumber) {
      do {
        this.holidaysForm.get('holiday' + i.toString()).setValue(null);
        this.holidaysForm.removeControl('holiday' + i.toString());
        i++
      } while (i <= this.oldNumber)
    }
    const numbers = Array(val).fill(val, 0, 365).map((_, idx) => idx + 1)
    numbers.forEach((num) => {
      const fc = new FormControl('', FormValidations.Calendar(this.valForm.get('year').value));
      this.holidaysForm.addControl('holiday' + num.toString(), fc)
    })
    this.numberOfHolidays = numbers;
    this.oldNumber = val;
  }

.html

                        <div class="col-md-4 mda-form-group">
                            <input class="mda-form-control" type="number" min="0" max="365"
                                formControlName="numberOfHolidays"
                                (change)="dynamicForm(valForm.get('numberOfHolidays').value)" />
                            <label>Total de Feriados</label>
                        </div>
                        <div [formGroup]="holidaysForm">
                            <div class="mda-form-group" *ngFor="let num of numberOfHolidays">
                                <input class="mda-form-control" type="date" formControlName="holiday{{num}}" />
                                <label>Feriado {{num}}</label>
                                <app-error-msg [control]="holidaysForm.get('holiday'+num)" label="Feriado">
                                </app-error-msg>
                            </div>
                        </div>

In theory the code works well and without errors, the problem is that the result is always this:

Main Form

  Valores: 
 {
  "dentistId": null,
  "initialHour": null,
  "endHour": null,
  "numberOfHolidays": 3,
  "appointmentsInterval": null,
  "year": null,
  "workDays": [
    false,
    false,
    false,
    false,
    false,
    false,
    false
  ],
  "holidays": null
}

Holiday Form

 {
  "holiday1": "2020-01-01",
  "holiday2": "2020-03-01",
  "holiday3": "2020-02-01"
}

Does anyone have any idea what I might be doing wrong? Thankful,


Solution

  • The problem seems to be you are using holidaysForm before you ever put values in it. So at the point where you are creating the object to loop through to create your array, that object will have no properties.

     buildHolidays() {
    if (typeof this.valForm !== 'undefined') {
      let teste = Object.assign({}, this.holidaysForm.value);   // this line
      this.holidays = new Array();
      Object.values(teste).forEach((v) => {
        this.holidays.push(v);
      })
      console.log(this.holidays);
      const values = this.holidays.map((v)=> new FormControl(v));      
      return this.fb.array(values);
    }
    

    }

    I would figure out how to get values to use in this method to make it all work. And remember, you can always add a formArray after the creation of your original formgroup via group.addControl('controlName', myFormArray);

    Best of luck, and as always Happy Coding