Angular 4 - Beginner to Pro. Stuck on Reactive Forms -> Form Array

I am working on the new-course-component lesson. I am getting error TS7015: Element implicitly has an ‘any’ type because index expression is not of type ‘number’.

*8 ngFor=“let topic of form.get((‘topics’)[‘controls’])”

The TS file looks like:
import { FormArray, FormControl, FormGroup } from ‘@angular/forms’;

import { Component, OnInit } from ‘@angular/core’;

@Component({

selector: ‘new-course-form’,

templateUrl: ‘./new-course-form.component.html’,

styleUrls: [’./new-course-form.component.css’]

})

export class NewCourseFormComponent implements OnInit {

form = new FormGroup({

topics: new FormArray([])

});

constructor() { }

addTopic(topic: HTMLInputElement) {

console.log(topic.value);

(this.form.get('topics') as FormArray).push(new FormControl(topic.value));

return this.form.get('topics') as FormArray;

}

ngOnInit(): void {

}

}

The html file looks like:

<ul class="list-group">
    <li
        *ngFor="let topic of form.get(('topics')['controls'])"
        class="list-group-item" >
    </li>
</ul>

Spent several hours looking on other forums. No luck. Does anyone know what this error is?

hi, I too spent quite some time trying to figure out the problem. The thing is the method “controls” exists only in the FormArray class and is not available for the FormGroup class which is why it doesn’t work.

the insctruction: " *ngFor=“let topic of form.get(‘topics’).controls” apply the control method to a FormGroup class simply because form.get(‘topics’) returns a FormGroup class.

One way around is to cast the FormGroup into a FormArray class.

Good luck.

Took some playing with, but seeing/borrowing code from the add method helped. The nesting combined with generics was a bit confusing, but one thing that helped it click was breaking down the “add” method to see that essentially we were adding a FormControl to a FormArray.

Component:

  getAllTopics(): FormControl[] {
    return (this.newForm.get('topics') as FormArray).controls as FormControl[];
  }

Template:

<li *ngFor="let topic of getAllTopics()"
            class="list-group-item">
            {{ topic.value }}
        </li>

Would have saved some time by moving on and refactoring like Mosh did, which updated it to the below:

Component:

addTopic(topic: HTMLInputElement) {
    this.topics.push(new FormControl(topic.value));
    topic.value = '';
  }

  get topics() {
    return this.newForm.get('topics') as FormArray;
  }

Template:

<li *ngFor="let topic of topics.controls"
            class="list-group-item">
            {{ topic.value }}
        </li>

Works for me this way:

*ngFor="let topic of form.get('topics')?.['controls']"