How to set value to form control in Reactive Forms in Angular
Solution 1
Setting or Updating of Reactive Forms Form Control values can be done using both patchValue and setValue. However, it might be better to use patchValue in some instances.
patchValue
does not require all controls to be specified within the parameters in order to update/set the value of your Form Controls. On the other hand, setValue
requires all Form Control values to be filled in, and it will return an error if any of your controls are not specified within the parameter.
In this scenario, we will want to use patchValue, since we are only updating user
and questioning
:
this.qService.editQue([params["id"]]).subscribe(res => {
this.question = res;
this.editqueForm.patchValue({
user: this.question.user,
questioning: this.question.questioning
});
});
EDIT: If you feel like doing some of ES6's Object Destructuring, you may be interested to do this instead 🙃
const { user, questioning } = this.question;
this.editqueForm.patchValue({
user,
questioning
});
Ta-dah!
Solution 2
In Reactive Form, there are 2 primary solutions to update value(s) of form field(s).
setValue:
-
Initialize Model Structure in Constructor:
this.newForm = this.formBuilder.group({ firstName: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(8)]], lastName: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(8)]] });
-
If you want to update all fields of form:
this.newForm.setValue({ firstName: 'abc', lastName: 'def' });
-
If you want to update specific field of form:
this.newForm.controls.firstName.setValue('abc');
Note: It’s mandatory to provide complete model structure for all form field controls within the FormGroup. If you miss any property or subset collections, then it will throw an exception.
patchValue:
-
If you want to update some/ specific fields of form:
this.newForm.patchValue({ firstName: 'abc' });
Note: It’s not mandatory to provide model structure for all/ any form field controls within the FormGroup. If you miss any property or subset collections, then it will not throw any exception.
Solution 3
Try this.
editqueForm = this.fb.group({
user: [this.question.user],
questioning: [this.question.questioning, Validators.required],
questionType: [this.question.questionType, Validators.required],
options: new FormArray([])
})
setValue() and patchValue()
if you want to set the value of one control, this will not work, therefor you have to set the value of both controls:
formgroup.setValue({name: ‘abc’, age: ‘25’});
It is necessary to mention all the controls inside the method. If this is not done, it will throw an error.
On the other hand patchvalue()
is a lot easier on that part, let’s say you only want to assign the name as a new value:
formgroup.patchValue({name:’abc’});
Solution 4
The "usual" solution is make a function that return an empty formGroup or a fullfilled formGroup
createFormGroup(data:any)
{
return this.fb.group({
user: [data?data.user:null],
questioning: [data?data.questioning:null, Validators.required],
questionType: [data?data.questionType, Validators.required],
options: new FormArray([this.createArray(data?data.options:null])
})
}
//return an array of formGroup
createArray(data:any[]|null):FormGroup[]
{
return data.map(x=>this.fb.group({
....
})
}
then, in SUBSCRIBE, you call the function
this.qService.editQue([params["id"]]).subscribe(res => {
this.editqueForm = this.createFormGroup(res);
});
be carefull!, your form must include an *ngIf to avoid initial error
<form *ngIf="editqueForm" [formGroup]="editqueForm">
....
</form>
Solution 5
To assign value to a single Form control/individually, I propose to use setValue in the following way:
this.editqueForm.get('user').setValue(this.question.user);
this.editqueForm.get('questioning').setValue(this.question.questioning);
Related videos on Youtube
sun
Updated on February 20, 2021Comments
-
sun about 3 years
Hi Everyone I'm new to angular. Actually, I'm trying to subscribe data from a service and that data, I'm passing to form control of mine from (example, it's like an edit form).
import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators, FormArray, FormControl } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; import { QuestionService } from '../shared/question.service'; @Component({ selector: 'app-update-que', templateUrl: './update-que.component.html', styleUrls: ['./update-que.component.scss'] }) export class UpdateQueComponent implements OnInit { questionsTypes = ['Text Type', 'Multiple choice', 'Single Select']; selectedQuestionType: string = ""; question: any = {}; constructor(private route: ActivatedRoute, private router: Router, private qService: QuestionService, private fb: FormBuilder) { } ngOnInit() { this.getQuebyid(); } getQuebyid(){ this.route.params.subscribe(params => { this.qService.editQue([params['id']]).subscribe(res =>{ this.question = res; }); }); } editqueForm = this.fb.group({ user: [''], questioning: ['', Validators.required], questionType: ['', Validators.required], options: new FormArray([]) }) setValue(){ this.editqueForm.setValue({user: this.question.user, questioning: this.question.questioning}) } }
if I use
[(ngModule)]
on my form field to set the value to my element it is working fine and showing a warning it'll be deprecated in angular 7 version.<textarea formControlName="questioning" [(ngModule)]="question.questioning" cols="70" rows="4"></textarea>
So, I set the values to my form control by doing below but the element is not showing those values.
setValue(){ this.editqueForm.setValue({user: this.question.user, questioning: this.question.questioning}) }
can anyone tell me how to set values to mine reactive form. Please suggest me.
-
Sachin Gupta about 5 yearsCan you please share the details how
setValue
andpatchValue
are different and why it would work in this scenario. -
wentjun about 5 yearsYes, I have actually included it. Sorry for being vague in my initial edit.
-
sun about 5 yearsHi @wentjun it's not working. still, my form is empty only. it's not showing the data.
-
wentjun about 5 yearsOh, you should call your method within the
subscribe
-
wentjun about 5 yearsI have updated my answer. Just to check,
this.question
contains a value, right? Try runningconsole.log(this.question)
.It isn't undefined or something? -
Eliseo about 5 yearsTAB, that's not work, when defined editqueForm, "this.question" has no value.
-
TAB about 5 yearsI have done it in my subcriber as : ngAfterViewInit(): void { this.childDetailDS$.subscribe((data) => { this.gDetailDS = data; this.cityPlaceForm = this.formBuilder.group({ cpCode: [this.gDetailDS.cpCode, Validators.required], cpName: [this.gDetailDS.cpName, Validators.required], province: [this.gDetailDS.province], status: [this.gDetailDS.status], versionNo: [this.gDetailDS.versionNo] }); });
-
Eliseo about 5 yearsNOT use ngAfterViewInit -yes, you don't know if in ngAfterViewInit you has value-, you must create the Form in "subscribe", see my answer
-
DINESH Adhikari about 4 yearsgetting this error Expression has changed after it was checked. Previous value: 'ng-valid: false'. Current value: 'ng-valid: true'.
-
devan about 4 yearsIn the 3rd point it should be corrected as , If you want to update specific field of form: this.newForm.controls.firstName.setValue('abc');
-
Kedar Km over 2 yearsThanks for saving my day, its helps me to reduce lot of code. Cheers :)
-
Janatbek Orozaly over 2 years@SachinGupta, sc-consulting.medium.com/…