Angular2 - reactive forms and multiple checkboxes not behaving correctly

I'm looking into reactive forms some more, and I want to have multiple checkboxes for a property that is an array (like hobby). So I defined the group as follows:

this.myForm = this.fb.group({

    name: ['', Validators.required],

    hobbies: this.fb.array([])

});

      

Hobbies are an array: hobbies = ['Cooking', 'Swimming', 'Hiking', 'Dancing'];

Now, in HTML, I have defined checkboxes like this:

<div>
  <span *ngFor="let hobby of hobbies">
    <label>
      <input type="checkbox" [value]="hobby" (click)="addToHobby(hobby)"> {{hobby}}
    </label>  
    <br />
  </span>
</div>

      

Now when inspecting an element, it doesn't add it to the hobby property at all, it just duplicates the actual HTML element. What am I doing wrong?

Here's the code: https://plnkr.co/edit/j8V189VoWKvloNgwOr7p?p=preview

+3


source to share


1 answer


OK I managed to get something to work. The link is available below, but first of all, here's my chain of thought.

First, we just need to define an array of all the values, maybe we'll get this from a web service, but still I'm mocking them like this:

hobbies = [new Hobby(1, 'Cooking'), new Hobby(2, 'Swimming'), new Hobby(3, 'Hiking'), new Hobby(4, 'Dancing')];

I have intentionally added an id so that it will more closely mimic the real world. Now we need to define the shape. Since multiple checkboxes won't work, I decided to present an array of individual checkboxes, each with multiple attributes, but at least two are needed: a boolean to decide if that checkbox was selected in the array, and a name so we can know what we're selecting.

To achieve this, we need to first create an array that will fit the shape, which is done like this:

    let hobbiesArray = [];

    for (let hobby of this.hobbies) {
      hobbiesArray.push(this.fb.group({
        isChosen: false,
        name: hobby.hobbyName,
        id: hobby.id
      }));
    }

      

As you can see, I created a new one fb.group

for each hobby, and they are all placed in an array. This array is then used to create the form as follows:

    this.myForm = this.fb.group({
      hobbiesList: this.fb.array(hobbiesArray)
    });

      



Now we have fb.array

of fb.groups

. Now when it comes to HTML I have several problems. The logic is "go through myForm.hobbiesList

and manipulate isChosen

, keeping the name

read-only view. Here is the code."

<div formArrayName="hobbiesList">
  <div *ngFor="let hobby of hobbiesList.controls; let i=index" [formGroupName]="i" >
    <input type="checkbox" formControlName="isChosen" /> {{hobby.controls.name.value}}
  </div>
</div> 

      

Here's my concern: can I just write the name like this {{hobby.controls.name.value}}

:? What harm can this do? Am I breaking any Angular2 / 4 rules?

OK, so when confirming the selected hobbies, we get an actual array with name and ids (no values isChosen

) like this:

submitMe(): void {
    let items = this.myForm.value;
    this.mySelectedHobbies = items.hobbiesList.filter(x => x.isChosen).map(x => { return { name: x.name, id: x.id }; });
}

      

So this is my project. I'm not sure if everything is resolved what I did, but I find this to be the easiest way to solve the problem. What do you guys think?

Here's the code: https://plnkr.co/edit/8OKiQMK788R2uCt2OWzm?p=preview

+3


source







All Articles