For an application I'm building, I'm retrieving data from an API and setting my form value directly with that response. For that I'm using the reactive forms module. I've built the form so that it matches the object I'm getting from the API. The problem is that some fields are supposed to be an object (FormGroup), but are NULL when empty. This results in the error "Cannot convert undefined or null to object".
FormGroup instance:
note: this.formBuilder.group({
turnbook_file: [''],
note: [''],
additional_files: ['']
});
Response from API
note: NULL
My thought was that maybe it's possibile to put an OR statement or something where you define the FormGroup like this:
note: this.formBuilder.group({
turnbook_file: [''],
note: [''],
additional_files: ['']
} | NULL);
patchValue()linkPatches the value of the FormGroup . It accepts an object with control names as keys, and does its best to match the values to the correct controls in the group.
The difference is that with setValue we must include all the controls, while with the patchValue you can exclude some controls.
So basically when we call setValue, patchValue, disable, enable control it triggers value change by default. If we had not setted emitEvent to false, it would trigger valueChange so parent form would trigger unnecessary api which we want to avoid here.
patchvalue or setvalue of formbuilder does not mark field as dirty or touched.
Two solutions come to mind
@NgModule({...})
export class AppModule {
constructor() {
const builtInFunction = FormGroup.prototype.patchValue;
FormGroup.prototype.patchValue = function (value, options?) {
builtInFunction.call(this, value || {}, options);
}
}
}
import {FormGroup, ValidatorFn, AbstractControlOptions, AsyncValidatorFn} from '@angular/forms';
export class MyFormGroup extends FormGroup {
constructor(
controls: {[key: string]: any},
validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null,
asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null
) {
super(controls, validatorOrOpts, asyncValidator);
}
patchValue(value: {[key: string]: any}, options: {onlySelf?: boolean, emitEvent?: boolean} = {}) {
super.patchValue(value || {}, options);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With