5

I build a Form in angular2 and typescript. I try to add a list of checkboxes dynamically and it's not working for me, Where is my mistake?

The template code:

<div formArrayName="categories">
   <div class="form-group" *ngFor="let category of updateDetailsForm.controls.categories.controls; let i = index">
      <label>
        <input type="checkbox" formControlName="{‌{i}}">
          {‌{category.name}}
      </label>
   </div>
</div>

The Typescript code:

updateDetailsForm: FormGroup;
private categories : Category[] = []

constructor(private router: Router,
            private ss : SearchService,
            private formBuilder: FormBuilder)
{
   this.initForm() // before the categories loaded
   this.ss.getAllCategories().subscribe(
     data => {
       this.categories = data
       this.initForm() // refresh the form with categories
     }
   )
 }

initForm() {
  let allCategories: FormArray = new FormArray([]);
  for (let i = 0; i < this.categories.length; i++) {
    allCategories.push(
      new FormGroup({
        'name': new FormControl([this.categories[i].categoryName])
      })
    )
  }
  this.updateDetailsForm = this.formBuilder.group({
    'image' : [''],
    'categories': allCategories
  })
}

This is my UI result, and I get the following error:

"inline template:17:33 caused by: control.registerOnChange is not a function"

enter image description here

The number of checkboxes is correct but the text is missing and I can't update the form result with user selection.

  1. What the error means?

  2. How can I insert the right text next the checkbox?

  3. How can update the user selection into the form value?

2 Answers 2

4

You've built out your form model in such a way that we'll need to access each FormGroup that you pushed onto the array and then access the named control within:

<span formGroupName="{{i}}">
  <input type="checkbox" formControlName="{{category.name}}">
  {{category.name}}
</span>

We'll also need to tweak how we're pushing values so that the name is set uniquely instead of always set as "name":

let fg = new FormGroup({});
fg.addControl(this.categories[i].name, new FormControl(false))
allCategories.push(fg)

Here's a plunker to demo it: http://plnkr.co/edit/OTiqwr1oCb8uEThQyDHx?p=preview

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

Comments

4

I think because of same name categories of your component variable and form group control you are getting error. Check it by making below change in your component and form HTML :

You can check FormArrayName directive for more reference.

//Component

updateDetailsForm: FormGroup;
private allCategories : Category[] = []

constructor(private router: Router,
            private ss : SearchService,
            private formBuilder: FormBuilder) {
  this.initForm() // before the categories loaded
  this.ss.getAllCategories().subscribe(
    data => {
      this.allCategories = data
      this.initForm() // refresh the form with categories
    }
  )
}
initForm() {
  let allCategories: FormArray = new FormArray([]);
  for (let i = 0; i < this.allCategories.length; i++) {
    allCategories.push(new FormControl());
  }
  this.updateDetailsForm = this.formBuilder.group({
    'image' : [''],
    'categories': allCategories
  })
}

// Form HTML

<div formArrayName="categories">
   <div class="form-group" *ngFor="let category of categories.controls; let i = index">
      <label>
        <input type="checkbox" formControlName="i">
          {‌{allCategories[i].name}}
      </label>
   </div>
</div>

1 Comment

Thanks but I checked it and I have same issues.

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.