207

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.

6 Answers 6

437

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.

Sign up to request clarification or add additional context in comments.

8 Comments

Wonder why on earth the Angular team did this
@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.
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.
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.
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().
|
20

Another option that I use is:

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

Comments

14

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 

Comments

5

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.

1 Comment

I'm glad it's valuable to you ... :)
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(); } 

Comments

1

I find it interesting to mention that if all controls are disabled

this.form = new FormGroup({ a: new FormControl({value: 'a', disabled: true}), b: new FormControl({value: 'b', disabled: true}), c: new FormControl({value: null, disabled: true}), }); 

the entire form is also marked as disabled

this.form.disabled = true; this.form.status = 'DISABLED'; 

and when we get the value of the form with this.form.value we get the value of all(!) controls and not an empty object as one would expect:

this.form.value = { a: 'a', b: 'b', c: null }; 

1 Comment

Not only interesting, but also very unexpected I would say... See also this bug report on GitHub: github.com/angular/angular/issues/42630

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.