我和我的同事目前正在处理一个客户项目。使用 NestJS 作为后端,Angular 作为前端,数据库是 MySQL。
我们正在努力解决以下问题,但我们都不知道如何解决此问题:
//imports
@Entity()
export class Movie {
@Column({ nullable: true })
dfffCopies: number;
//more stuff
}
this.form = this.fb.group({ dfffCopies: new FormControl(0)})
//imports
export class CreateMovieDto {
@ApiProperty()
@IsOptional()
dfffCopies: number;
//more stuff
}
现在的问题是,当用户什么都不输入时,我的同事想发送一个
NULL
、undefined
、空字符串或类似的东西,而不是 0 作为数字,以便后端可以将此值保存为空了。
然而,当他这样做时,后端会抛出错误
"incorrect integer value: 'null'"
Number(dfffCopies)
的操作,我们已经尝试过这样做,但问题是,我们可能还有大约 50 多个整数值要保存在这个电影实体中,我几乎将整个 dto 保存到数据库中,如下所示:
//when saving
const movie = this.create(createMovieDto);
await this.save(movie);
//when editing
await this.update({ id }, createMovieDto);
如果我这样做,我必须将 dto 中的每个值包装到 if 语句中以检查它是否存在。
现在的问题是:
我或我的同事如何更改代码以接受 NULL、未定义、NaN 或整数字段上的其他内容并将其空保存到数据库中?他说我们可以将所有字段的后端从数字/整数更改为字符串,但说实话,这感觉不是解决方案。
好吧,所以我基本上发现我可以通过创建自己的装饰器来解决这个问题,该装饰器深受这个 toBoolean Decorator 的启发,现在,当我的同事向我发送一个空字符串 `` 或
null
时,它会将其转换数据库中为 NULL。在 dto 之前
import { Transform } from 'class-transformer';
const ToInteger = () => {
const toPlain = Transform(
({ value }) => {
return value;
},
{
toPlainOnly: true,
},
);
const toClass = (target: any, key: string) => {
return Transform(
({ obj }) => {
return valueToInteger(obj[key]);
},
{
toClassOnly: true,
},
)(target, key);
};
return function (target: any, key: string) {
toPlain(target, key);
toClass(target, key);
};
};
const valueToInteger = (value: any) => {
if (value === undefined) {
return undefined;
}
if (isNaN(value)) {
return null;
}
if (value === '') {
return null;
}
if (value === 'null') {
return null;
}
const x = parseInt(value);
return x;
};
export { ToInteger };
之后我只需将装饰器导入到我的 dto 中并为此变量设置它
//imports
export class CreateMovieDto {
@ApiProperty()
@IsOptional()
@ToInteger()
dfffCopies: number;
//more stuff
}