187

I have noticed that if I disable a control on an Angular 2 reactive form then the control does not get included in the form.value. For example, if I define my form like below:

this.notelinkingForm = new FormGroup({
    Enabled: new FormControl(settings.Enabled, Validators.required),
    LinkToPreceeding: new FormControl({value: settings.LinkToPreceeding, disabled: !settings.Enabled}, Validators.required),
    LinkingTolerance: new FormControl({value: settings.LinkingTolerance, disabled: !settings.Enabled}, Validators.required)
});

and check the this.notelinkingForm.value, if all the controls are enabled then output would be:

{"Enabled":true, "LinkToPreceeding": true, LinkingTolerance:"100"} 

However, when some of the controls are disabled it would be:

{"Enabled":true} 

Notice how the disabled controls are excluded.

My intent is that when the form changes I want to be able to pass the form.value with all the properties in it off to my rest API. This won't be possible obviously if it does not contain the disabled items.

Am I missing something here or is this the expected behavior? Is there a way to tell Angular to include the disabled items in the form.value?

Welcome your thoughts.

Stefan Svrkota
  • 48,787
  • 9
  • 98
  • 87
Jim Culverwell
  • 2,623
  • 6
  • 25
  • 28

5 Answers5

395

You can use:

this.notelinkingForm.getRawValue()

From Angular docs:

If you'd like to include all values regardless of disabled status, use this method. Otherwise, the value property is the best way to get the value of the group.

Roy
  • 7,811
  • 4
  • 24
  • 47
Sasxa
  • 40,334
  • 16
  • 88
  • 102
  • 100
    Wonder why on earth the Angular team did this – inorganik Apr 02 '19 at 15:36
  • 1
    @inorganik They did it because it is possible to enable a disabled control and edit its value. In this case getRawValue() will return an object with the tampered value. – Danish Nov 22 '19 at 05:03
  • 11
    This is actually a good thing. For example, I know that the values of my disabled controls are not going to change so I don't want to include them in the save API because I assigned those controls a value from the database in the first place. But in some cases, I actually do want to include those controls which have the values assigned from the front end and they are not stored in the DB and this function covers it. It's always good to have both options. – ChiragMS Jun 02 '20 at 14:33
  • 4
    Thats true @ChiragMS. I like that aspect as long as I have a choice between `readonly` and `disabled`. But this isn't the case for e.g. checkboxes and radio buttons as I described in the answer below. In those cases I didn't like it that I have to get the data differently and code something specifically for that case. – Sandro Aug 12 '20 at 13:18
  • It's a pointless argument to "remove" the value because someone could tamper with it. NEVER trust client-side data. You should _always_ expect someone to tamper with your data, and recheck it on the server-side anyway. This is just another annoyance of Angular. Besides, Angular 11 does _not_ include disabled values, even when using getRawValue(). – thinkOfaNumber Mar 29 '21 at 06:38
  • @inorganik, It's behavioral and both options are provided. FormGroup.value is a property that contains all aggregated enabled values and FormGroup.getRawValue() is a function that gets all aggregated values including disabled ones. – Paul-Sebastian Manole Jul 05 '21 at 22:52
  • Strangely, `FormGroup.value` *does* display disabled values when *all* values are disabled... – Elias Strehle Aug 10 '21 at 14:12
13

Another option that I use is:

this.form.controls['LinkToPreceeding'].value;

jwheron
  • 2,553
  • 2
  • 30
  • 40
12

Thank you @Sasxa for getting me 80% what I needed.

For those of you looking for a solution to the same problem but for nested forms I was able to solve by changing my usual

this.notelinkingForm.get('nestedForm').value

to

this.notelinkingForm.getRawValue().nestedForm
eper
  • 1,043
  • 10
  • 10
3

If you use readonly instead of disabled it's still not editable while the data will be included in the form. But that isn't possible in all cases. E.g. it's not available for radio buttons and checkboxes. See MDN web docs. In those cases you have to apply for the other solutions provided here.

Sandro
  • 1,757
  • 1
  • 19
  • 29
1

There's a two way we can get disabled form values. First

 onSubmit(){
 for (const prop in this.formControl.controls) {
      this.formControl.value[prop] = this.formControl.controls[prop].value;
    }
}

Second way You can enable form at onSubmit event

 onSubmit(){
     this.formControl.enable() 
   //Your logical/operational statement goes here

  //at last if you wish you can again disable your form like this
   this.formControl.disable();
}