对于我正在构建的应用程序,我正在从API检索数据,并使用该响应直接设置表单。为此,我正在使用反应形式模块。我建立了表格,使其与我从API获取的对象匹配。问题在于某些字段应该是对象(FormGroup),但为空时为NULL。这将导致错误“无法将未定义或null转换为对象”。
FormGroup实例:
note: this.formBuilder.group({
turnbook_file: [''],
note: [''],
additional_files: ['']
});
来自API的响应
note: NULL
我的想法是,可能会放置OR语句或在您定义FormGroup的地方添加这样的内容:
note: this.formBuilder.group({
turnbook_file: [''],
note: [''],
additional_files: ['']
} | NULL);
我对Angular来说还很陌生,所以我完全不了解这个问题。我在Angular Reactive Forms文档中找不到解决方案。我希望这里有人可以帮助我!
答案 0 :(得分:1)
您可以尝试使用lodash pickBy方法包装api响应,然后再使用它。
import * as _ from 'lodash';
...
//fetch data from API
note.patchValue(
_.pickBy(apiResponse)
);
...
答案 1 :(得分:0)
您可以这样定义表格
note =new FormGroup({
'turnbook_file': new FormControl(null),
'note: new FormControl(null),
'additional_files': new FormControl(null)
})
答案 2 :(得分:0)
如果您定义表单和控件,则必须将值传递给它,因此,如果您的响应为空,则设置这样的表单控件的值
note.setValue({
'turnbook_file': data.turnbook_file == null ? "": data.turnbook_file,
'note: ,data.note == null ? "": data.note,
'additional_files': data.additional_files == null ? "":
data.additional_files,
})
答案 3 :(得分:0)
您可以在修补表单之前简单地过滤掉这些值
const obj = {
foo: "bar",
bar: null,
cat: undefined,
dog: "bark"
}
const truthy = Object.keys(obj).filter(item => obj[item] != undefined || obj[item] != null );
const newObj = {};
truthy.forEach(item =>Object.assign(newObj, { [item]: obj[item]}));
console.log(newObj) // { foo: "bar", dog: "bark" }
一旦您过滤掉了伪造的值,就可以用它来修补表格
答案 4 :(得分:0)
想到两个解决方案
@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);
}
}
答案 5 :(得分:0)
简短答案:
在Angular Forms API的当前实现中-无法创建/修补具有FormGroup
或null
值的undefined
。
原因:在所有new FormGroup(), formBuilder.group(), patchValue()
场景中,都有一个方法Object.keys()
的调用,该方法会抛出错误Cannot convert undefined or null to object
(根据JS规范),如果我们将null/undefined
作为参数传递。
证明:
FormBuilder
的{{1}}方法(source code link):
group()
group(controlsConfig: {[key: string]: any}, ...) {
const controls = this._reduceControls(controlsConfig);
...
}
_reduceControls(controlsConfig: {[k: string]: any}) {
Object.keys(controlsConfig).forEach(...);
...
}
的{{1}}(source code link):
FormGroup
解决方法:
patchValue
而不是null; patchValue(value: {[key: string]: any}, ...) {
Object.keys(value).forEach(...);
...
}
类并创建一个新的类,您可以在其中重写{}
:检查参数是否为FormGroup
-改用空对象。constructor/patchValue
服务并创建您自己的Singleton服务(在您的应用程序中随处使用),您可以在其中覆盖null/undefined
方法(请参见上一节)。答案 6 :(得分:0)
改进 bestbrain10 答案。您可以同时使用 pickBy 和 isDefined。
import { isEmpty, pickBy ,isUndefined,isNull} from 'lodash';
// Fetch data and remove all falsy keys
this.formgroup.patchValue(
_.omitBy(formData, (v) => _.isUndefined(v) || _.isNull(v) || v === ''));