Matthew Brown
Matthew Brown

Reputation: 5116

Manually Set Value for FormBuilder Control

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>

Upvotes: 302

Views: 634226

Answers (11)

Raihan Ridoy
Raihan Ridoy

Reputation: 788

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

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

Upvotes: 47

Sadid Khan
Sadid Khan

Reputation: 1985

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

Upvotes: 12

Simon_Weaver
Simon_Weaver

Reputation: 145880

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 } );

Upvotes: -1

vivekkurien
vivekkurien

Reputation: 1594

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"});

Upvotes: 20

chovy
chovy

Reputation: 75656

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

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

Upvotes: 10

Thierry Templier
Thierry Templier

Reputation: 202138

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.

Upvotes: 10

tanveer ahmad dar
tanveer ahmad dar

Reputation: 3372

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

Upvotes: 23

Filoche
Filoche

Reputation: 5542

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.

Upvotes: 539

zurfyx
zurfyx

Reputation: 32757

@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

Upvotes: 3

user688074
user688074

Reputation:

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

If you don't want manually set each field.

Upvotes: 5

Angular University
Angular University

Reputation: 43087

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.

Upvotes: 124

Related Questions