0

I am trying to traverse through a nested FormArray to keep track of a set of questions, each given their own 'FormControl'. I have created a FormArray called 'groups' as such. The hierarchy goes Groups[Questions[Answers]]

constructor(private surveyService: SurveyService, @Inject(FormBuilder) private fb: FormBuilder) {
    this.survey = <Survey>SURVEYS[0];

    this.reactiveForm = fb.group({
      name: ['', Validators.required],
      groups: fb.array(this.getGroups())
    });

}

getGroups() : AbstractControl[] {
    return Array.apply(null,
      Array(this.survey.groups.length)).map((x, index) => new FormArray(this.getQuestions(index)))
  }

getQuestions(index) : AbstractControl[] {
    return Array.apply(null,
      Array(this.survey.groups[index].questions.length)).map(x => new FormControl(x, Validators.required));
  }

Here is my HTML code:

<form [formGroup]="reactiveForm">
  <div formArrayName="groups">
    <div *ngFor="let group of survey.groups; index as groupIndex" [formArrayName]=groupIndex>
      <h1>{{group.groupName}}</h1>
      <div *ngFor="let question of group.questions; index as questionIndex" [formArrayName]=questionIndex>
        <h2>{{question.question}}</h2>
        <label *ngFor="let answer of question.responses ; index as answerIndex">
          <input type="radio" [value]=answerIndex [formControlName]=questionIndex>{{answer}}
        </label>
      </div>
    </div>
  </div>
</form>

I figure it to work as such: the first ngFor pulls the array of Questions, the second ngFor pulls the array of answers, and then the final ngFor uses [formControlName] in order to bind each question to the same Control, giving it a unique answer. However, the error I get is this:

Error: Cannot find control with path: 'groups -> 0 -> 0 -> 0'

If Groups[0] is an array and Groups[0][0] is also an array, why does the [0] of that suddenly not exist anymore? How should one go about traversing a FormArray like this?

0

2 Answers 2

2

Here is what you have created:

enter image description here

Now look at your template:

<form [formGroup]="reactiveForm">
  <div formArrayName="groups">
    <div ... [formArrayName]=groupIndex>
      ...
      <div ... [formArrayName]=questionIndex>
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
             Do you see such FormArray in your FormGroup? I don't
        <...
        <label *ngFor="let answer of question.responses ; index as answerIndex">
          <input ...[formControlName]=questionIndex>...
        </label>
      </div>
    </div>
  </div>
</form>

As you can see you Angular can't find FormControl by path groups -> 0 -> 0 -> 0 because it should be groups -> 0 -> 0

So if you will remove redundant [formArrayName]=questionIndex directive then it should work.

Ng-run Example

Tip: use <pre>{{reactiveForm.value | json}}</pre> to test FormGroup structure

Sign up to request clarification or add additional context in comments.

Comments

0

For demo I used simple structure:

export class Group {
  title: string;
  questions: Question[] = [];

}

export class Question {
  title: string;
  answers: Answer[] = [];    
}

export class Answer {
  id: number;
  title: string;
}

StackBlitz Demo

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.