Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 5 - Form Control with objects

Tags:

I'm currently working on an Angular application backed by Django.

One part of the application is that it needs to display a list of members. The members array looks somewhat like this:

[   {     name: 'John Smith',     id: 3,     score_set: [...]   },   {     name: 'Jane Doe',     id: 7,     score_set: [...]   },   {     name: 'Bill Appleseed',     id: 3,     score_set: [...]   },   {     name: 'Bob Lee',     id: 3,     score_set: [...]   } ] 

I got that working, but I also needed the user to be able to edit the names of those members. I tried using Reactive Forms to get this working:

First, I made a FormGroup consisting of just one FormArray. This FormArray basically contained all of the member objects:

this.form = this.fb.group({   roster: this.fb.array(this.members.map((elem) => [elem, Validators.required])) }); 

Next, I wrote out the template for the component:

<form>   <div [formGroup]="form">     <div formArrayName="roster">       <div *ngFor="let control of form.controls.roster.controls">         <div class="form-group">           <input class="form-control" [formControl]="control" placeholder="Enter name">         </div>       </div>     </div>   </div> </form> 

But instead of displaying the name property of each member it just tries to display the whole object, making [Object object]. Is there any way to configure each FormControl to use the name property as a value?

I want it so that only the name is displayed in the <input>, and when the user edits the <input> it updates the name property of the object, while retaining all the other properties.

Any help would be appreciated!

like image 566
Oliver Ni Avatar asked Apr 02 '18 01:04

Oliver Ni


1 Answers

Since you want to keep the full object, you'll have to create formGroups, like this:

interface Member {   id: number;   name: string; }  ngOnInit(): void {   this.formGroup = this.formBuilder.group({     roster: this.formBuilder.array(this.members.map(member => this.createMemberGroup(member))),   }); }  createMemberGroup(member: Member): FormGroup {   return this.formBuilder.group({     ...member,     name: [member.name, Validators.required],   }); } 

HTML:

<form class="container pt-2" [formGroup]="formGroup">   <div formArrayName="roster">     <div        [formGroupName]="index"        *ngFor="let control of formGroup.get('roster').controls; index as index">       <div class="form-group">         <input            class="form-control"            formControlName="name"            placeholder="Enter name"            [class.is-invalid]="control.invalid">         <small class="text-danger" *ngIf="control.invalid">Required</small>       </div>     </div>   </div> </form> 

DEMO

like image 174
developer033 Avatar answered Oct 03 '22 19:10

developer033