Manually Set Value for FormBuilder Control

FormsComponentsAngular

Forms Problem Overview


This is driving me nuts, I'm under the gun and can't afford to spend another whole day on this.

I am trying to manually set a control value ('dept') within the component, and it's just not working - even the new value logs to console properly.

Here is the FormBuilder Instance:

initForm() {
  this.form = this.fb.group({
    'name': ['', Validators.required],
    'dept': ['', Validators.required],
    'description': ['', Validators.required],
  });
}

This is the event handler that receives the selected dept:

deptSelected(selected: { id: string; text: string }) {
  console.log(selected) // Shows proper selection!
 
  // This is how I am trying to set the value
  this.form.controls['dept'].value = selected.id;
}

Now when the form is submitted and I log out this.form the field is still blank! I've seen other ppl use updateValue() but this is beta.1 and I don't see that as a valid method to call on the control.

I have also tried to call updateValueAndValidity() with no success :(.

I would just use ngControl="dept" on the form element, like I'm doing with the rest of the form but its a custom directive/component.

<ng-select
  [data]="dept"
  [multiple]="false"
  [items]="depts"
  (selected)="deptSelected($event)" <!-- This is how the value gets to me -->
  [placeholder]="'No Dept Selected'">
</ng-select>

Forms Solutions


Solution 1 - Forms

Updated: 19/03/2017

this.form.controls['dept'].setValue(selected.id);

OLD:

For now we are forced to do a type cast:

(<Control>this.form.controls['dept']).updateValue(selected.id)

Not very elegant I agree. Hope this gets improved in future versions.

Solution 2 - Forms

In Angular 2 Final (RC5+) there are new APIs for updating form values. The patchValue() API method supports partial form updates, where we only need to specify some of the fields:

this.form.patchValue({id: selected.id})

There is also the setValue() API method that needs an object with all the form fields. If there is a field missing, we will get an error.

Solution 3 - Forms

Aangular 2 final has updated APIs. They have added many methods for this.

To update the form control from controller do this:

this.form.controls['dept'].setValue(selected.id);

this.form.controls['dept'].patchValue(selected.id);

No need to reset the errors

References

https://angular.io/docs/ts/latest/api/forms/index/FormControl-class.html

https://toddmotto.com/angular-2-form-controls-patch-value-set-value

Solution 4 - Forms

If you are using form control then the simplest way to do this:

this.FormName.get('ControlName').setValue(value);

Solution 5 - Forms

You can use the following methods to update the value of a reactive form control. Any of the following method will suit for your need.

Methods using setValue()

this.form.get("dept").setValue(selected.id);
this.form.controls["dept"].setValue(selected.id);

Methods using patchValue()

this.form.get("dept").patchValue(selected.id);
this.form.controls['dept'].patchValue(selected.id);
this.form.patchValue({"dept": selected.id});

Last method will loop thorough all the controls in the form so it is not preferred when updating single control

You can use any of the method inside the event handler

deptSelected(selected: { id: string; text: string }) {
     // any of the above method can be added here
}

You can update multiple controls in the form group if required using the

this.form.patchValue({"dept": selected.id, "description":"description value"});

Solution 6 - Forms

You could try this:

deptSelected(selected: { id: string; text: string }) {
  console.log(selected) // Shows proper selection!

  // This is how I am trying to set the value
  this.form.controls['dept'].updateValue(selected.id);
}

For more details, you could have a look at the corresponding JS Doc regarding the second parameter of the updateValue method: https://github.com/angular/angular/blob/master/modules/angular2/src/common/forms/model.ts#L269.

Solution 7 - Forms

I know the answer is already given but I want give a bit brief answer how to update value of a form so that other new comers can get a clear idea.

your form structure is so perfect to use it as an example. so, throughout my answer I will denote it as the form.

this.form = this.fb.group({
    'name': ['', Validators.required],
    'dept': ['', Validators.required],
    'description': ['', Validators.required]
  });

so our form is a FormGroup type of object that has three FormControl.

> 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. > From Angular official documentation here

so, When updating the value for a form group instance that contains multiple controls, but you may only want to update parts of the model. patchValue() is the one you are looking for.

lets see example. When you use patchValue()

this.form.patchValue({
    dept: 1 
});
//here we are just updating only dept field and it will work.

but when you use setValue() you need to update the full model as it strictly adheres the structure of the form group. so, if we write

this.form.setValue({
    dept: 1 
});
// it will throw error.

We must pass all the properties of the form group model. like this

this.form.setValue({
      name: 'Mr. Bean'
      dept: 1,
      description: 'spome description'
  });

but I don't use this style frequently. I prefer using the following approach that helps to keep my code cleaner and more understandable.

What I do is, I declare all the controls as a seperate variable and use setValue() to update that specific control.

for the above form, I will do something like this.

get companyIdentifier(): FormControl {
    return this.form.get('name') as FormControl;
}

get dept(): FormControl {
    return this.form.get('dept') as FormControl;
}

get description(): FormControl {
    return this.form.get('description') as FormControl;
}

when you need to update the form control just use that property to update it. In the example the questioner tried to update the dept form control when user select an item from the drop down list.

deptSelected(selected: { id: string; text: string }) {
  console.log(selected) // Shows proper selection!
  
  // instead of using this.form.controls['dept'].setValue(selected.id), I prefer the following.

  this.dept.setValue(selected.id); // this.dept is the property that returns the 'dept' FormControl of the form.
}

I suggest to have a look FormGroup API to get know how of all the properties and methods of FormGroup.

Additional: to know about getter see here

Solution 8 - Forms

None of these worked for me. I had to do:

  this.myForm.get('myVal').setValue(val);

Solution 9 - Forms

  let cloneObj = Object.assign({}, this.form.getRawValue(), someClass);
  this.form.complexForm.patchValue(cloneObj);

If you don't want manually set each field.

Solution 10 - Forms

@Filoche's Angular 2 updated solution. Using FormControl

(<Control>this.form.controls['dept']).updateValue(selected.id)

import { FormControl } from '@angular/forms';

(<FormControl>this.form.controls['dept']).setValue(selected.id));

Alternatively you can use @AngularUniversity's solution which uses patchValue

Solution 11 - Forms

Tip: If you're using setValue but not providing every property on the form you'll get an error:

Must supply a value for form control with name: 'stateOrProvince'.

So you may be tempted to use patchValue, but this can be dangerous if you're trying to update a whole form. I have an address that may not have stateOrProvince or stateCd depending upon whether it is US or worldwide.

Instead you can update like this - which will use the nulls as defaults:

this.form.setValue( { stateOrProvince: null, stateCd: null, ...address } );

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMatthew BrownView Question on Stackoverflow
Solution 1 - FormsFilocheView Answer on Stackoverflow
Solution 2 - FormsAngular UniversityView Answer on Stackoverflow
Solution 3 - Formstanveer ahmad darView Answer on Stackoverflow
Solution 4 - FormsRaihan RidoyView Answer on Stackoverflow
Solution 5 - FormsvivekkurienView Answer on Stackoverflow
Solution 6 - FormsThierry TemplierView Answer on Stackoverflow
Solution 7 - FormsSadid KhanView Answer on Stackoverflow
Solution 8 - FormschovyView Answer on Stackoverflow
Solution 9 - FormsBendYourTaxesView Answer on Stackoverflow
Solution 10 - FormszurfyxView Answer on Stackoverflow
Solution 11 - FormsSimon_WeaverView Answer on Stackoverflow