5

I'm trying to get something going with reactive forms but having difficulty achieving what I thought would be straightforward.

I would like to loop over elements and display them as form controls.

I currently have:

@Component({
  selector: 'app-reactive-form-test',
  styleUrls: ['./reactive-form-test.component.scss'],
  template: `
    <form [formGroup]="questionForm">
      <ng-container formArrayName="questions" *ngFor="let question of questionForm.controls; let i = index">
<input type="text" formControlName="i">
</ng-container>
    </form>
  `
})
export class ReactiveFormTestComponent implements OnInit {
  questionForm: FormGroup;

  questions: ScheduledQuestionInterface[];

  constructor(private fb: FormBuilder) { }

  ngOnInit(): void {
    this.questionForm = this.fb.group({
      questions: this.fb.array([])
    });
    this.questions = [];
    this.questions.push(new ScheduledQuestion(1, 1, 1, 1));
    this.questions.push(new ScheduledQuestion(2, 3, 1, 2));
    this.questions.push(new ScheduledQuestion(3, 4, 1, 3));
    this.questions.forEach(value => {
      const control = this.questionForm.get('questions') as FormArray;
      control.push(this.fb.group({
        id: [value.id],
        deliveryDateTime: [value.deliveryDateTime]
      }));
    });
  }
}

Right now I'm getting the below error:

Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays..

What do I need to do to this code to simply show 3 text fields from the 3 ScheduledQuestion objects?

2 Answers 2

6

questionForm.controls is an Object with the keys as the formControls basically in your case

  {
     questions: []
  }

You are trying to loop over the above object which is not iterable hence the error

Below should work

@Component({
  selector: 'app-reactive-form-test',
  styleUrls: ['./reactive-form-test.component.scss'],
  template: `
    <form [formGroup]="questionForm">
      <ng-container formArrayName="questions">
        <ng-container *ngFor="let question of questionControls.controls; let i = index">
<input type="text" [formGroupName]="i">
      </ng-container>
      
</ng-container>
    </form>
  `
})
export class ReactiveFormTestComponent implements OnInit {
  questionForm: FormGroup;

  questions: ScheduledQuestionInterface[];
  get questionControls() {
     return this.questionForm.get('questions') as FormArray;
  }
  

  constructor(private fb: FormBuilder) { }

  ngOnInit(): void {
    this.questionForm = this.fb.group({
      questions: this.fb.array([])
    });
    this.questions = [];
    this.questions.push(new ScheduledQuestion(1, 1, 1, 1));
    this.questions.push(new ScheduledQuestion(2, 3, 1, 2));
    this.questions.push(new ScheduledQuestion(3, 4, 1, 3));
    this.questions.forEach(value => {
      const control = this.questionForm.get('questions') as FormArray;
      control.push(this.fb.group({
        id: [value.id],
        deliveryDateTime: [value.deliveryDateTime]
      }));
    });
  }
}
Sign up to request clarification or add additional context in comments.

3 Comments

What is that get questionControls()? Is get a keyword?
@MawgsaysreinstateMonica that is a "getter" very helpful when you have a property that is dependent on another property see this developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Oh, wow, it's plain JS. I know what getters & setters are, just didn't know it was a keyword. Thanks (+1)
3

The issue here is that you are trying to loop over questionForm.controls, which is not iterable, it's an object, and it's not what you need, also you don't need to repeat the form array, you need to loop over the controls in this array

an example from Angular References:

<div formArrayName="cities">
  <div *ngFor="let city of cities.controls; index as i">
    <input [formControlName]="i" placeholder="City">
  </div>
</div>

so, you need to have NgFor for your inputs/controls, and the loop should be over questions.controls

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.