title: How to sum the value from dynamic nested array field and create a object for per input field
body: <p>I am trying to develop a number grading system for a course using Angular 8. The real scenario is quite complex, so I separated the part and created a new project to explain where I have the problem. If you look at the image you will get an idea, what I am trying to accomplish. Assume this is the grade form of one course. For a course, there can have different exams. Students who are enrolled in this course, they will attend those specific exams for this course and then teacher will submit the number using this form. Suppose, for the first row first column (Mid Exam), the form should not allow you to provide more than 25 marks or less than zero. If you put 20 on the Mid Exam field then <code>Total</code> will show 20, GP will show 0.00, Grade will show F. Then if you put 30 on the Final exam field, Total value will be updated to 50, GP will be updated to 0.00 and will be updated to F. Again if you put 40 on the Assessment field,  Total value will be updated to 90, GP will be updated to 4.00 and will be updated to A. Same thing will be happened to for all the row. If you click on the Save button, numbers will be submitted.</p>
  
  <p><a href="https://i.stack.imgur.com/37MDo.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/37MDo.png" alt="enter image description here"></a></p>
  
  <p>Now I am describing the code that I tried and my problem, here <code>studentList</code>,  <code>examList</code> and <code>gradePointList</code> array will populate the data for a course from backend service. I created <code>populateSomeDemoData</code> method to generate this data. studentList is an array of the Student object which contains students' id and name. examList is an array of the Exam object which contains exam id, exam name and total marks of this exam. gradePointList contains the range of the number of letter grade and grade point. Suppose if the total mark is between 90 (minimumNumber) and 100 (maximumNumber) the grade point will be 4.00 and letter grade will be A. I tried to create a form <code>gradeForm</code> and applied a loop on examList for per row to create input field. But for this, I couldn't able to access the specific field using form control that's why I failed to calculate total marks and grade point for a row. Also for the same reason, I failed to create the list of Grade object which will be sent to the backend. <code>Grade</code> is the object of every field which will contain student, exam and number. If a field is updated, this grade object will also be updated. If Save button triggers, this number list will be passed to the backend.</p>
  
  <p>HTML part is:</p>
  
  <pre><code>&lt;form [formGroup]="gradeForm" (ngSubmit)="saveGrade()"&gt;
    &lt;table&gt;
      &lt;thead&gt;
      &lt;tr&gt;
        &lt;th&gt; #&lt;/th&gt;
        &lt;th&gt;Student&lt;/th&gt;
        &lt;th *ngFor="let exam of examList"&gt;{{exam.name}} ({{exam.marks}}%)&lt;/th&gt;
        &lt;th&gt;Total&lt;/th&gt;
        &lt;th&gt;GP&lt;/th&gt;
        &lt;th&gt;Grade&lt;/th&gt;
      &lt;/tr&gt;
      &lt;/thead&gt;
  
      &lt;tbody&gt;
      &lt;tr *ngFor="let student of studentList; let i = index"&gt;
        &lt;th&gt; {{ i + 1 }} &lt;/th&gt;
        &lt;th&gt; {{ student.id }} &lt;br/&gt; {{student.name}} &lt;/th&gt;
        &lt;th *ngFor="let grade of gradeFields.controls; let j = index" formArrayName="gradeFields"&gt;
          &lt;input type="number" [formControlName]="j"&gt;
        &lt;/th&gt;
        &lt;th&gt;??&lt;/th&gt;
        &lt;th&gt;??&lt;/th&gt;
        &lt;th&gt;??&lt;/th&gt;
      &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  
    &lt;div class="wrapper"&gt;
      &lt;button class="button"&gt;Save Grade&lt;/button&gt;
    &lt;/div&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>TypeScript Part is: </p>
  
  <pre><code>export class AppComponent {
  
    public gradeForm: FormGroup;
  
    // This arrays will populate dynamically from the database
    public examList: Exam[] = [];
    public studentList: Student[] = [];
    public gradePointList: GradePoint[] = [];
    public gradeList: Grade[] = [];
  
    constructor(private formBuilder: FormBuilder) {
  
      this.populateSomeDemoData();
  
      this.createGradeForm();
    }
  
    createGradeForm(): void {
      this.gradeForm = this.formBuilder.group({
        gradeFields: this.formBuilder.array([
          this.formBuilder.control('')
        ])
      });
  
      for (let i = 0; i &lt; this.examList.length - 1; i++) {
        this.gradeFields.push(this.formBuilder.control(''));
      }
    }
  
    get gradeFields() {
      return this.gradeForm.get('gradeFields') as FormArray;
    }
  
    saveGrade(): void {
      console.log(this.gradeForm.get('gradeFields').value);
      console.log(this.gradeList);
      console.log('Grade List Saved');
    }
  
    populateSomeDemoData(): void {
      // Static value for populating arrays for easy explanation
      const midTerm = new Exam();
      midTerm.id = '1';
      midTerm.name = 'Mid Exam';
      midTerm.marks = 25;
  
      const finalExam = new Exam();
      finalExam.id = '2';
      finalExam.name = 'Final Exam';
      finalExam.marks = 30;
  
      const assessmentExam = new Exam();
      assessmentExam.id = '3';
      assessmentExam.name = 'Assessment';
      assessmentExam.marks = 40;
  
      const attendance = new Exam();
      attendance.id = '4';
      attendance.name = 'Attendance';
      attendance.marks = 5;
  
      this.examList.push(midTerm);
      this.examList.push(finalExam);
      this.examList.push(assessmentExam);
      this.examList.push(attendance);
  
  
      // Static value for populating arrays for easy explanation
      const student1 = new Student();
      student1.id = '14101561';
      student1.name = 'Petey Cruiser';
  
      const student2 = new Student();
      student2.id = '14112201';
      student2.name = 'Bob Frapples';
  
      const student3 = new Student();
      student3.id = '14112202';
      student3.name = 'Paul Molive';
  
      const student4 = new Student();
      student4.id = '16113004';
      student4.name = 'Anna Mull';
  
      const student5 = new Student();
      student5.id = '16113005';
      student5.name = 'Gail Forcewind';
  
      this.studentList.push(student1);
      this.studentList.push(student2);
      this.studentList.push(student3);
      this.studentList.push(student4);
      this.studentList.push(student5);
  
  
      // Static value for populating arrays for easy explanation
      const aGradePoint = new GradePoint();
      aGradePoint.minimumNumber = 90;
      aGradePoint.maximumNumber = 100;
      aGradePoint.gradePoint = 4;
      aGradePoint.letterGrade = 'A';
  
      const bGradePoint = new GradePoint();
      bGradePoint.minimumNumber = 80;
      bGradePoint.maximumNumber = 89;
      bGradePoint.gradePoint = 3.5;
      bGradePoint.letterGrade = 'B';
  
      const cGradePoint = new GradePoint();
      cGradePoint.minimumNumber = 70;
      cGradePoint.maximumNumber = 79;
      cGradePoint.gradePoint = 3;
      cGradePoint.letterGrade = 'C';
  
      const dGradePoint = new GradePoint();
      dGradePoint.minimumNumber = 60;
      dGradePoint.maximumNumber = 69;
      dGradePoint.gradePoint = 2.5;
      dGradePoint.letterGrade = 'D';
  
      const fGradePoint = new GradePoint();
      fGradePoint.minimumNumber = 0;
      fGradePoint.maximumNumber = 59;
      fGradePoint.gradePoint = 0;
      fGradePoint.letterGrade = 'F';
      this.gradePointList.push(aGradePoint);
      this.gradePointList.push(bGradePoint);
      this.gradePointList.push(cGradePoint);
      this.gradePointList.push(dGradePoint);
      this.gradePointList.push(fGradePoint);
    }
  }
  
  export class Student {
    public id: string;
    public name: string;
  
    constructor(student?) {
      student = student || {};
      this.id = student.id || null;
      this.name = student.name || null;
    }
  }
  
  export class Exam {
    public id: string;
    public name: string;
    public marks: number;
  
    constructor(exam?) {
      exam = exam || {};
      this.id = exam.id || null;
      this.name = exam.name || null;
      this.marks = exam.marks || 0;
    }
  }
  
  export class GradePoint {
    public minimumNumber: number;
    public maximumNumber: number;
    public gradePoint: number;
    public letterGrade: string;
  
    constructor(gradePoint?) {
      gradePoint = gradePoint || {};
      this.minimumNumber = gradePoint.minimumNumber || 0;
      this.maximumNumber = gradePoint.maximumNumber || 59;
      this.gradePoint = gradePoint.gradePoint || 0;
      this.letterGrade = gradePoint.letterGrade || 'F';
    }
  }
  
  export class Grade {
    public student: Student;
    public exam: Exam;
    public number: number;
  
    constructor(grade?) {
      grade = grade || {};
      this.student = grade.student || null;
      this.exam = grade.exam || null;
      this.number = grade.number || null;
    }
  }
  </code></pre>
  
  <p>I have created a StackBlitz for better understanding of the code. Please click on this link to view the code. <a href="https://stackblitz.com/edit/grade-upload" rel="nofollow noreferrer">Click here</a></p>
  
  <p>I saw a lot of post which is related to Form Arrays but my scenario is quite different. Here I don't have any Add button to push array or calculate the values. And there are fixed forms for all cases. But in my case, the array also will be generated from the list because examList is dynamic. </p>
  
  <p>I assume I have problem with creating on the form or my approaches are wrong. Please help me to accomplish my objective generate total marks and creating Grade list. It would be appreciated. Thanks in advance.</p>