0

I have the need for a table containing a checkbox for every row in the table. I'm using Angular 9.

The table is defined in a form and I use an ngFor to create each row in the table. In the ngFor I loop over a collection of messages and I create a row for each message.

The user should be able to check the checkbox and the push a button to resend the selected messages.

The way I've written my code I do get errors I can't explain.

I have created a stackblitz thingy to share my code. https://stackblitz.com/edit/angular-4qqrzf?file=src%2Fapp%2Fapp.component.ts There are some things wrong with this code in Stackblitz. The most annoying one is that it keeps saying that it's loading while nothing seems to happen. I must be missing something there.

If I run the code on my own system I get this error:

[Error] ERROR – TypeError: this.form.controls.orders.push is not a function. (In 'this.form.controls.orders.push(control)', 'this.form.controls.orders.push' is undefined) — app.component.ts:36
TypeError: this.form.controls.orders.push is not a function. (In 'this.form.controls.orders.push(control)', 'this.form.controls.orders.push' is undefined) — app.component.ts:36
    defaultErrorLogger (vendor.js:12499)
    handleError (vendor.js:12552)
    run (polyfills.js:136)
    (anonymous function) (vendor.js:45404)
    onInvoke (vendor.js:44403)
    run (polyfills.js:136)
    (anonymous function) (polyfills.js:870)
    onInvokeTask (vendor.js:44381)
    runTask (polyfills.js:180)
    drainMicroTaskQueue (polyfills.js:582)
    promiseReactionJob

I have copied most of the code from https://stackblitz.com/edit/angular-stszta?file=src%2Fapp%2Fapp.module.ts where this problem does not occur.

app.component.ts:

import { Component } from '@angular/core';
import {FormArray, FormBuilder, FormControl, FormGroup} from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  form: FormGroup;
  ordersData = [
    { id: 100, name: 'order 1' },
    { id: 200, name: 'order 2' },
    { id: 300, name: 'order 3' },
    { id: 400, name: 'order 4' }
  ];

  berichten = [
    {messageId: 123},
    {messageId: 234},
    {messageId: 345},
    {messageId: 456},
    {messageId: 567}
  ];

  constructor(private formBuilder: FormBuilder) {
    this.form = this.formBuilder.group({
      orders: []
    });
    this.addCheckboxes();
  }

  private addCheckboxes() {
    this.ordersData.forEach((o, i) => {
      const control = new FormControl(i === 0); // if first item set to true, else false
      (this.form.controls.orders as FormArray).push(control);
    });
  }

  submit() {
    const selectedOrderIds = this.form.value.orders
      .map((v, i) => (v ? this.ordersData[i].id : null))
      .filter(v => v !== null);
    console.log(selectedOrderIds);
  }
}

app.component.html:

  <table>
    <thead>
    <tr>
      <td>
        <b>Selection</b>
      </td>
      <td>
        <b>MessageId</b>
      </td>
    </tr>
    </thead>
    <tbody>
    <tr *ngFor="let bericht of berichten; let i = index" >
      <td>
        <input type="checkbox" [formControlName]="i">
      </td>
      <td>
        {{bericht.messageId}}
      </td>
    </tr>
    </tbody>
  </table>
</form>

What am I doing wrong? (In Stackblitz and in my code)

3
  • Can you include the relevant code in the question? Commented Apr 30, 2020 at 13:37
  • stackblitz is not working, change <app-root>loading</app-root> Commented Apr 30, 2020 at 13:41
  • code added. Fixed stackBlitz. Commented Apr 30, 2020 at 13:42

1 Answer 1

1

Form is shown with these changes:

//constructor     
orders: new FormArray([])



`//addCheckboxes`
(this.form.get('orders') as FormArray).push(control);

In template remove the binding to a control which does not exist

[formControlName]="i"
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. This works. Would you mind to explain, if possible, why:(this.form.get('orders') as FormArray).push(control); works and my: (this.form.controls.orders as FormArray).push(control); doesn't? My example was copied from a working solution on StackBlitz .
this.form.controls is an array of FormControls and does not have a property orders. this.form.get('orders') asks in the form for a control (can be a group/control/formarray) with the name 'orders'

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.