Reputation: 1273
I have a basic form shown below. I make a call to an API to grab the user's personal info and I want to fill the form fields with the appropriate values. I have been trying to use patchValue
but I cannot get it to work.
<form
(ngSubmit)="(onSubmit)"
class="example-form"
[formGroup]="firstFormGroup"
#registerForm="ngForm"
>
<mat-form-field class="example-full-width">
<input matInput placeholder="Company" formControlName="company" required autofocus />
<mat-error *ngIf="firstFormGroup.get('company').hasError('required')">
Company name is
<strong>required</strong>
</mat-error>
</mat-form-field>
<table class="example-full-width" cellspacing="0">
<tr>
<td>
<mat-form-field class="example-full-width">
<input matInput placeholder="First name" formControlName="first_name" required />
<mat-error *ngIf="firstFormGroup.get('first_name').hasError('required')">
First name is
<strong>required</strong>
</mat-error>
</mat-form-field>
</td>
<td>
<mat-form-field class="example-full-width">
<input matInput placeholder="Last Name" formControlName="last_name" required />
<mat-error *ngIf="firstFormGroup.get('last_name').hasError('required')">
Last name is
<strong>required</strong>
</mat-error>
</mat-form-field>
</td>
</tr>
<tr>
<td>
<mat-form-field class="example-full-width">
<input matInput placeholder="Email" formControlName="email" required />
<mat-error
*ngIf="firstFormGroup.get('email').hasError('email') && !email.hasError('required')"
>
Please enter a valid email address
</mat-error>
<mat-error *ngIf="firstFormGroup.get('email').hasError('required')">
Email is
<strong>required</strong>
</mat-error>
</mat-form-field>
</td>
</tr>
</table>
<p>
<mat-form-field class="example-full-width">
<textarea matInput placeholder="Address" formControlName="address" required></textarea>
</mat-form-field>
<mat-form-field class="example-full-width">
<textarea matInput placeholder="Address 2"></textarea>
</mat-form-field>
</p>
<table class="example-full-width" cellspacing="0">
<tr>
<td>
<mat-form-field class="example-full-width">
<input matInput placeholder="City" formControlName="city" required />
</mat-form-field>
</td>
<td>
<mat-form-field class="example-full-width">
<mat-select placeholder="State" formControlName="state" required>
<mat-option>None</mat-option>
<mat-option *ngFor="let state of states" [value]="state">{{ state }}</mat-option>
</mat-select>
</mat-form-field>
</td>
<td>
<mat-form-field class="example-full-width">
<input
matInput
#postalCode
maxlength="5"
placeholder="Postal Code"
value=""
formControlName="zip"
required
/>
<mat-hint align="end">{{ postalCode.value.length }} / 5</mat-hint>
</mat-form-field>
</td>
</tr>
</table>
<button type="submit" class="register" mat-button (click)="check()" color="primary">Save</button>
<!-- <button type="submit" [disabled]="!registerForm.form.valid" class="register" mat-button (click)="check()" color="primary">Save</button> -->
</form>
Here's my ts file:
import { Component, OnInit } from '@angular/core'
import { LoginService } from '../login.service'
import { FormControl, Validators, FormGroup, FormBuilder } from '@angular/forms'
@Component({
selector: 'app-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.css'],
})
export class ProfileComponent implements OnInit {
firstFormGroup: FormGroup
profileInfo: Object[]
constructor(private _formBuilder: FormBuilder, private _auth: LoginService) {}
getInfo() {
let value
this._auth.profile({ username: 'evanlalo' }).subscribe((res) => {
for (const item in res) {
if (this.firstFormGroup.value.hasOwnProperty(item)) {
value = res[item]
console.log(value)
this.firstFormGroup.patchValue({ item: value })
console.log(item, res[item])
}
}
})
}
ngOnInit() {
this.firstFormGroup = this._formBuilder.group({
company: new FormControl('', Validators.required),
first_name: new FormControl('', Validators.required),
last_name: new FormControl('', Validators.required),
address: new FormControl('', Validators.required),
city: new FormControl('', Validators.required),
state: new FormControl('', Validators.required),
zip: new FormControl('', Validators.required),
email: new FormControl('', [Validators.required, Validators.email]),
})
this.getInfo()
}
}
All of the keys match the form field names but it will not work if I use the item
variable. The weird thing is that if I hard code the field name IE company
, the field will be set.
Any help would be appreciated.
thanks,
Upvotes: 5
Views: 30909
Reputation: 8563
maybe, the control doesn't exist.
You may control it and register if it doesn't.
Then you shall be able to use patch, and I would recommend using patch over set.
if(!this.firstFormGroup.get('item')) {
this.firstFormGroup.registerControl('item', value)
}
Upvotes: 0
Reputation: 5033
If you are working with Angular 9+ read this.
From Angular docs, it does make sense to use setValue({key: value})
instead of patchValue({key: value})
because setValue
does not swallow errors. You will be thrown off if your object is nested/complex.
There are two ways to update the model value:
Use the setValue() method to set a new value for an individual control. The setValue() method strictly adheres to the structure of
the form group and replaces the entire value for the control.
Use the patchValue() method to replace any properties defined in the object that have changed in the form model.
The strict checks of the setValue() method help catch nesting errors in complex forms, while patchValue() fails silently on those errors.
Also you cannot use patchValue({[key]: value}); //no parenthesis
Upvotes: 2
Reputation: 143
If somehow any value part is undefined in patchValue, then also it did not work. for e.g. in below example if i want to patch a few columns like id, projectName etc. and somehow this.project.Id element is undefined (not filled from service) then also patchValue will not work without throwing any error.
this.projectForm.patchValue({
id: this.project.Id,
ProjectName: this.project.ProjectName
});
Upvotes: 4
Reputation: 4145
In your case patchValue syntax is wrong.
Correct syntax is,
this.firstFormGroup.patchValue({[item]: value});
use [item] instead of item
[item] it means dynamic keys added to formGroup
Upvotes: 15