How to make these things Dynamic in Angular?

Viewed 52

I am try to build a complete dynamic web page.

This is my code so far:

my component.ts :

import { Component, OnInit } from '@angular/core';
import { Quiz1 } from 'src/app/models/quiz1.model';
import { Quiz1Service } from 'src/app/services/quiz1.service';
import {FormControl, FormGroup} from '@angular/forms';


@Component({
  selector: 'app-quiz1',
  templateUrl: './quiz1.component.html',
  styleUrls: ['./quiz1.component.css']
})
export class Quiz1Component implements OnInit {

  questions?: Quiz1[];
  currentQuestion: Quiz1 = {};
  currentIndex = -1;
  answer!: FormGroup;
  result1?: String;
  result2?: String;
  
  constructor(private quiz1Service: Quiz1Service) { }

  ngOnInit(): void {
    this.retrieveQuestions();
    this.answer = new FormGroup({
      Ans1: new FormControl(''),
      Ans2: new FormControl('')
    });
  }

  retrieveQuestions(): void {
    this.quiz1Service.getAll()
      .subscribe({
        next: (data: any) => {
          this.questions = data;
          console.log(data);
        },
        error: (e: any) => console.error(e)
      });
  }

  onSubmit(){
    this.result1 = this.answer.value.Ans1;
    this.result2 = this.answer.value.Ans2;
  }

}

and here is my component.html

<div class="container">
  <Form >
    <div [formGroup]="answer">
    <div *ngFor="let question of questions">
      <a>{{question.questionId}}. {{question.question}}</a><br>
      <input type="radio" formControlName="Ans{{question.questionId}}" value="A" >
      <label for="html">A. {{question.optionsA}}</label><br>

      <input type="radio" formControlName="Ans{{question.questionId}}" value="B" >
      <label for="html">B. {{question.optionsB}}</label><br>

      <input type="radio" formControlName="Ans{{question.questionId}}" value="C" >
      <label for="html">C. {{question.optionsC}}</label><br>

      <input type="radio" formControlName="Ans{{question.questionId}}" value="D" >
      <label for="html">D. {{question.optionsD}}</label><br>
    </div>
  </div>

    <button class="btn btn-primary " (click)="onSubmit()" type="button" >Submit</button>
  </Form>

  <div *ngIf="result1 != null">
    <table>
      <thead>
        <th>Question No.</th>
        <th>Correct Answer</th>
        <th>Your Answer</th>
      </thead>
      <tbody *ngFor="let question of questions">
        <td>{{question.questionId}}</td>
        <td>{{question.answer}}</td>
        <td>{{result1}}</td>
      </tbody>
    </table>
     </div>
</div>

What I want to do is:

First, I want to dynamically create new form control inside the form group according to number of records in questions.

Then, I want to store the values of ans1, ans2,... inside of a array instead of result1 and result2.

And lastly. I want to display that array inside of the table in html instead of result 1.

I tried various things but kept getting errors, can some body please help me?

1 Answers

First, I want to dynamically create new form control inside the form group according to number of records in questions.

ngOninit() {
  this.retrieveQuestions();
  
  // instantiate an empty formGroup.
  this.answer = new FormGroup({});

  // loop through the questions and add new formControl per question.
  this.questions.forEach(q => {
    this.answer.addControl(`Ans${q.questionId}`, new FormControl(''));
  });

}

Then, I want to store the values of ans1, ans2,... inside of a array instead of result1 and result2.


@Component({
 // ...
})
export class Quiz1Component implements OnInit {

  // make results an array of string.
  results: string[];


  onSubmit(){
    
    // loop through each answer and push it to the results array.
    Object.keys(this.answer.controls).forEach(key => {
        this.results.push(this.answer.get(key)!.value);
    });
  }

}

And lastly. I want to display that array inside of the table in html instead of result 1.

<div ng-if="results.length > 0">

    <table>
      <thead>
        <th>Question No.</th>
        <th>Correct Answer</th>
        <th>Your Answer</th>
      </thead>
      <tbody *ngFor="let question of questions; let i = index">
        <td>{{question.questionId}}</td>
        <td>{{question.answer}}</td>
        <td>{{results[i]}}</td>
      </tbody>
    </table>

</div>
Related