How to set value to form control in Reactive Forms in Angular

239,911

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);
Share:
239,911

Related videos on Youtube

sun
Author by

sun

Updated on February 20, 2021

Comments

  • sun
    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
    Sachin Gupta about 5 years
    Can you please share the details how setValue and patchValue are different and why it would work in this scenario.
  • wentjun
    wentjun about 5 years
    Yes, I have actually included it. Sorry for being vague in my initial edit.
  • sun
    sun about 5 years
    Hi @wentjun it's not working. still, my form is empty only. it's not showing the data.
  • wentjun
    wentjun about 5 years
    Oh, you should call your method within the subscribe
  • wentjun
    wentjun about 5 years
    I have updated my answer. Just to check, this.question contains a value, right? Try running console.log(this.question).It isn't undefined or something?
  • Eliseo
    Eliseo about 5 years
    TAB, that's not work, when defined editqueForm, "this.question" has no value.
  • TAB
    TAB about 5 years
    I 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
    Eliseo about 5 years
    NOT 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
    DINESH Adhikari about 4 years
    getting this error Expression has changed after it was checked. Previous value: 'ng-valid: false'. Current value: 'ng-valid: true'.
  • devan
    devan about 4 years
    In 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
    Kedar Km over 2 years
    Thanks for saving my day, its helps me to reduce lot of code. Cheers :)
  • Janatbek Orozaly
    Janatbek Orozaly over 2 years