26

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!

3
  • You're just missing the .name. Do it like this: roster: this.fb.array(this.members.map(elem => [elem.name, Validators.required])) Commented Apr 2, 2018 at 1:54
  • 3
    I could do that, but I want the FormControl to keep the object data as well, so I know which name goes with which object. Since I'm also going to add removing and adding members, if I only put the name in the FormControl I won't be able to know which object was edited. Commented Apr 2, 2018 at 2:05
  • 6
    I want the FormControl to internally keep the {name: string, id: number, score_set: any[]}, but I want it to display only name on the actual <input>. Is that possible? Commented Apr 2, 2018 at 2:06

1 Answer 1

29

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

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

4 Comments

Doesn't making a FormGroup require me to add input fields for the other properties? I only want name to be editable
Or is it possible to put the other properties into the FormGroup but not make <input>s for them
Add properties to a FormGroup doesn't necessarily means that you want to edit them (which is your case). Check the demo.
Ok the one point this answer is missing, is that you can then do 'control.value.id' inside the loop and it will do what you think it will. Thank you

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.