Angular FormGroup setValue and patchValue

By Arvind Rai, January 17, 2021
This page will walk through Angular setValue and patchValue methods of FormGroup. The setValue method sets a new value to the form controls of this FormGroup. The patchValue patches the new value of this FormGroup in best possible way. The difference between setValue and patchValue is that the object passed to setValue should match the structure of FormGroup object whereas it is not necessary for patchValue method.

Technologies Used

Find the technologies being used in our example.
1. Angular 11.0.3
2. Node.js 12.5.0
3. NPM 6.9.0

FormGroup.setValue

The setValue method sets a new value to the form controls of this FormGroup. The setValue accepts an object that matches the structure of the FormGroup with control names as keys. The object supplied to setValue should exactly match the structure of this form group i.e. the object should contain each and every form control names as keys.
Find the setValue method declaration from Angular doc.
setValue(value: { [key: string]: any; }, options: { onlySelf?: boolean; emitEvent?: boolean; } = {}): void 
value: The object that contains keys and values. The keys are control names.

options :

onlySelf: If true, the changes made to control affects only this control and not its parent. Default is false.
emitEvent: If true or not supplied, both statusChanges and valueChanges observables emit events with latest status and value when there is any change. If emitEvent is false, no events are emitted.

Suppose we have a FormGroup as below.
this.userForm = this.formBuilder.group({
	userName: ['', [Validators.required, Validators.maxLength(15)]],
	age: '',		
	gender: ['', Validators.required],
	isMarried: false,
	tc: ['', Validators.requiredTrue]
}); 
We can set new value to the above FormGroup using setValue dynamically as following.
this.userForm.setValue({
	userName: 'Mahesh', 
	age: 20,
	gender: 'male',
	isMarried: true, 
	tc: true
}); 

FormGroup.patchValue

The patchValue patches the value of this FormGroup in best possible way. The patchValue accepts the object with control names as keys. If the supplied object does not contain all the form controls as keys of this FormGroup object, patchValue sets new value only to those form controls which are available in supplied object .
Find the patchValue method declaration from Angular doc.
patchValue(value: { [key: string]: any; }, options: { onlySelf?: boolean; emitEvent?: boolean; } = {}): void 
value: The object that contains keys and values. The keys are control names.

options :

onlySelf: If true, the changes made to control affect only this control and not its parent. Default is false.
emitEvent: If true or not supplied, both statusChanges and valueChanges observables emit events with latest status and value when there is any change. If emitEvent is false, no events are emitted.

Find the sample code to patch value to userForm.
this.userForm.patchValue({
	userName: 'Mahesh', 
	gender: 'male',
	tc: true
}); 

Difference between setValue and patchValue

In our userForm, we have form controls as userName, age, gender, isMarried and tc.
1. If setValue is passed with an object that have lesser or greater number of keys as compared to form controls, then setValue will through error.
If patchValue is passed with an object that have lesser or greater number of keys as compared to form controls, then patchValue will patch value for those controls which are matching with this FormGroup structure and will not throw any error.
2. Suppose we pass an object to setValue with an extra key, let’s say, ‘xyz’ which are not part of the structure of userForm.
this.userForm.setValue({
	userName: 'Mahesh', 
	age: 20,
	gender: 'male',
	isMarried: true, 
	tc: true,
	xyz: true,
}); 
We will get error in browser console:
ERROR Error: Cannot find form control with name: xyz. 

Object with extra key will work with patchValue method.
this.userForm.patchValue({
	userName: 'Mahesh', 
	age: 20,
	gender: 'male',
	isMarried: true, 
	tc: true,
	xyz: true
}); 
The above code will not throw error and update the form control value for matching keys.
3. Suppose we pass an object to setValue with lesser number of form controls of userForm as keys, let’s say, we are excluding userName.
this.userForm.setValue({
	age: 20,
	gender: 'male',
	isMarried: true, 
	tc: true
}); 
We will get error in browser console:
ERROR Error: Must supply a value for form control with name: 'userName'. 
The same object will work with patchValue.
this.userForm.patchValue({
	age: 20,
	gender: 'male',
	isMarried: true, 
	tc: true
}); 
The above code will work and update userForm except userName.

Complete Example

user.component.ts
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';

@Component({
	selector: 'app-user',
	templateUrl: './user.component.html',
	styleUrls: ['./user.component.css']
})
export class UserComponent implements OnInit {
	isValidFormSubmitted = null;
	userForm: FormGroup;

	constructor(private formBuilder: FormBuilder) { }
	ngOnInit() {
		this.userForm = this.formBuilder.group({
			userName: ['', [Validators.required, Validators.maxLength(15)]],
			age: '',
			gender: ['', Validators.required],
			isMarried: false,
			tc: ['', Validators.requiredTrue]
		});
	}
	get userName() {
		return this.userForm.get('userName');
	}
	get gender() {
		return this.userForm.get('gender');
	}
	get tc() {
		return this.userForm.get('tc');
	}
	onFormSubmit() {
		this.isValidFormSubmitted = false;
		if (this.userForm.invalid) {
			return;
		}
		this.isValidFormSubmitted = true;
		console.log(this.userForm.value);
		this.resetForm(this.userForm);
	}
	resetForm(form: FormGroup) {
		form.reset();
	}
	setUserValues() {
		this.userForm.setValue({
			userName: 'Mahesh',
			age: 20,
			gender: 'male',
			isMarried: true,
			tc: true
		});
	}
	patchUserValues() {
		this.userForm.patchValue({
			userName: 'Mahesh',
			gender: 'male',
			tc: true
		});
	}
} 
user.component.html
<h3>User Form</h3>
<p *ngIf="isValidFormSubmitted" class="success">
	Form submitted successfully.
</p>
<form [formGroup]="userForm" (ngSubmit)="onFormSubmit()">
	<table>
		<tr>
			<td>Name:</td>
			<td>
				<input formControlName="userName">
				<div *ngIf="userName.errors && isValidFormSubmitted != null && !isValidFormSubmitted" class="error">
					<div *ngIf="userName.errors.required">
						Username required.
					</div>
					<div *ngIf="userName.errors.maxlength">
						Username can be max 15 characters long.
					</div>
				</div>
			</td>
		</tr>
		<tr>
			<td>Age:</td>
			<td>
				<input formControlName="age" type="number">
			</td>
		</tr>
		<tr>
			<td>Gender:</td>
			<td>
				<input type="radio" value="male" formControlName="gender"> Male
				<input type="radio" value="female" formControlName="gender"> Female
				<div *ngIf="gender.errors && isValidFormSubmitted != null && !isValidFormSubmitted" class="error">
					<div *ngIf="gender.errors.required">
						Gender required.
					</div>
				</div>
			</td>
		</tr>
		<tr>
			<td>Are you married? </td>
			<td>
				<input type="checkbox" formControlName="isMarried">
			</td>
		</tr>
		<tr>
			<td>Accept T & C </td>
			<td>
				<input type="checkbox" formControlName="tc">
				<div *ngIf="tc.invalid && isValidFormSubmitted != null && !isValidFormSubmitted" class="error">
					Accept T & C.
				</div>
			</td>
		</tr>
		<tr>
			<td colspan="2">
				<button>Submit</button>
				<button type="button" (click)="setUserValues()">Set User values</button>
				<button type="button" (click)="patchUserValues()">Patch User values</button>
			</td>
		</tr>
	</table>
</form> 
user.component.css
table {
    border-collapse: collapse;
}
table, th, td {
    border: 1px solid black;
}
.error {
    color: red;
}
.success {
    color: green;
} 
app.component.ts
import { Component } from '@angular/core';

@Component({
   selector: 'app-root',
   template: `
		<app-user></app-user>
             `
})
export class AppComponent { 
} 
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { UserComponent } from './user.component';

@NgModule({
      imports: [
            BrowserModule,
            ReactiveFormsModule
      ],
      declarations: [
            AppComponent,
            UserComponent
      ],
      providers: [
      ],
      bootstrap: [
            AppComponent
      ]
})
export class AppModule { } 

Run Application

To run the application, find the steps.
1. Download source code using download link given below on this page.
2. Use downloaded src in your Angular CLI application. To install Angular CLI, find the link.
3. Run ng serve using command prompt.
4. Access the URL http://localhost:4200
Click on the setValue button and it will set the values in the form. Find the print screen of the output.
Angular FormGroup setValue and patchValue

Reference

Angular FormGroup

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI







©2024 concretepage.com | Privacy Policy | Contact Us