0

I want to define a question which has some answers. Here is my code:

  formGroup!:FormGroup;
  answerFormGroup:FormGroup=this.formBuilder.group({
    text: ['d', Validators.required],
    value: [0, Validators.required]
  });
  ngOnInit() {
    this.formGroup = this.formBuilder.group({
      question:['',Validators.required],
      questionType: [1,Validators.required],
      answers: new FormArray([])
    });
   this.questionTypes=this.localDataService.questionType;
   this.addAnswer();
  }

   // convenience getters for easy access to form fields
   get answers() {
    return this.formGroup.controls["answers"] as FormArray;
  }

  addAnswer(){
    this.answers.push(this.formBuilder.group({
      text: ['d', Validators.required],
      value: [0]
    }));
  }

  submit(){
       console.log(JSON.stringify(this.formGroup.value));
  }

But when I submit my form the answer values are the default values and it does not change. In the form I changed the default value "d" to "b", and it is still "d". Here is the result:

{
  "question": "question1",
  "questionType": 1,
  "answers": [
    {
      "text": "d",
      "value": 0
    }
  ]
}

Here is the template:

<form class="question-card" [formGroup]="formGroup">
    <mat-form-field>
        <mat-label>Question</mat-label>
        <input matInput formControlName="question" placeholder="Question">
    </mat-form-field>
    <mat-form-field>
        <mat-label>Type</mat-label>
        <mat-select formControlName="questionTypeControl" (selectionChange)="updateQuestionType($event)">
            @for (item of questionTypes; track item) {
                <mat-option [value]="item.id">
                    <mat-icon>{{item.icon}}</mat-icon> {{item.text}}
                </mat-option>
            }
        </mat-select>
    </mat-form-field>  
    <div [formGroup]="answerFormGroup">
    @for(item of answers.controls; track item){
        <mat-form-field>
            <mat-label>Value</mat-label>
            <input matInput type="text" formControlName="value">
        </mat-form-field>
        <mat-icon class="delete-btn" (click)="deleteAnswer($event)">delete_forever</mat-icon>
        <mat-form-field>
            <mat-label>Text</mat-label>
            <input matInput type="text" formControlName="text">
        </mat-form-field>
    }
    </div>
    <button mat-mini-fab (click)="addAnswer()">
            <mat-icon>add</mat-icon>
    </button>
    <button type="button" (click)="submit()">Submit</button>
</form>
2
  • Could you show the template? Probably you are missing an assignment for the formControlName or formControl. Commented Nov 14, 2023 at 18:44
  • @Draess Dear Draess, I added my template. Commented Nov 14, 2023 at 19:45

1 Answer 1

1

You are updating the text control in the answerFormGroup FormGroup but not formGroup. From here:

<div [formGroup]="answerFormGroup">
  ...
</div>

In the formGroup template, you need to have the formArray control for the answers.

<form class="question-card" [formGroup]="formGroup">

  ...

  <ng-container formArrayName="answers">
    @for (item of answers.controls; track item; let i = $index) {

      <div [formGroupName]="i">
        <mat-form-field>
          <mat-label>Value</mat-label>
          <input matInput type="text" formControlName="value" />
        </mat-form-field>
        <mat-icon class="delete-btn" (click)="deleteAnswer($event)"
          >delete_forever</mat-icon
        >
        <mat-form-field>
          <mat-label>Text</mat-label>
          <input matInput type="text" formControlName="text" />
        </mat-form-field>
      </div>
    }
  </ng-container>

  ...

</form>

The @for syntax is a new feature in Angular 17 and quite new to me. If you are looking for the old way:

<ng-container formArrayName="answers">
  <ng-container *ngFor="let answer of answers.controls; let i = index">
    <div [formGroupName]="i"> 
    
    <mat-form-field>
      <mat-label>Value</mat-label>
      <input matInput type="text" formControlName="value" />
    </mat-form-field>
    <mat-icon class="delete-btn" (click)="deleteAnswer($event)"
      >delete_forever</mat-icon
    >
    <mat-form-field>
      <mat-label>Text</mat-label>
      <input matInput type="text" formControlName="text" />
    </mat-form-field>
  </div>
    
  </ng-container>
</ng-container>

Demo @ StackBlitz

Note that you are missing questionTypeControl control in the formGroup.

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

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.