Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to let Angular Reactive Forms PatchValue() ignore null value or undefined when patching a FormGroup

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);
like image 518
Thom Avatar asked Dec 13 '18 16:12

Thom


People also ask

What is the use of patchValue in angular?

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.

What is the difference between setValue and patchValue in angular?

The difference is that with setValue we must include all the controls, while with the patchValue you can exclude some controls.

Does patchValue trigger valueChanges?

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.

Does patchValue set dirty?

patchvalue or setvalue of formbuilder does not mark field as dirty or touched.


1 Answers

Two solutions come to mind

Modify FormGroup prototype

@NgModule({...})
export class AppModule {

  constructor() {
    const builtInFunction = FormGroup.prototype.patchValue;
    FormGroup.prototype.patchValue = function (value, options?) {
      builtInFunction.call(this, value || {}, options);
    }
  }

}

Extend FormGroup class

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

}
like image 153
displayName Avatar answered Sep 18 '22 08:09

displayName