Handling nested data in reactive forms

122 views Asked by At

I have to do a POST so we often make something like this:

const userData = this.userForm.value;

Suppose in the template you have:

<input type="text" id="userName" formControlName="userName">
<input type="email" id="userEmail" formControlName="userEmail">
<select id="userTypeId" formControlName="userTypeId">
  <option *ngFor="let userType of userTypes" [value]="userType.id">{{userType.name}}</option>
</select>

Then in your userData you'll have:

{
  userName: 'foo',
  userEmail: '[email protected]',
  userTypeId: '1'
}

This is fine, but now your API is waiting for:

{
  userName: string,
  userEmail: string,
  userType: UserType
}

where UserType

{
  id: string,
  name: string,
}

so you eventually do:

const userForAPI = {
  userName: userData.userName,
  userEmail: userData.userEmail,
  userType: { id: userData.userTypeId }
}

and then you go to

this.userService.createUser(userForAPI)

Now, I want to know if there is a possible alternative solution for not doing:

userType: { id: userData.userTypeId }

I mean, if you can model the template based on the api's model so that you can send this.userForm.value to the api.

1

There are 1 answers

3
Lazar Ljubenović On BEST ANSWER

The values for the select/option control can be custom object, and not just strings, if you use ngValue instead of value. This means that you can change your model to use userType instead of userTypeId.

<select id="userType" formControlName="userType">
  <option *ngFor="let userType of userTypes" [ngValue]="userType">{{userType.name}}</option>
</select>

The model will now contain, for example, the following.

{
  userName: 'foo',
  userEmail: '[email protected]',
  userType: {id: '1', name: 'foo1'},
}

Here's a demo.