Angular NestJS TypeORM 在整数/数字字段上保存 null

问题描述 投票:0回答:1

我和我的同事目前正在处理一个客户项目。使用 NestJS 作为后端,Angular 作为前端,数据库是 MySQL。

我们正在努力解决以下问题,但我们都不知道如何解决此问题:

  • 在 NestJS 后端的实体中,我们将列设置为数字(int),如下所示:

    //imports
    
    @Entity()
    export class Movie {
    
    @Column({ nullable: true })
    dfffCopies: number;
    
    //more stuff
    
    }

  • 在 Angular 前端,我的同事正在使用 Angular Formbuilder 设置一个表单,初始值为 0

    this.form = this.fb.group({ dfffCopies: new FormControl(0)})

  • 当他使用表单构建器发送此表单时,它会到达后端控制器,登陆到 dto 中

    //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 或整数字段上的其他内容并将其空保存到数据库中?他说我们可以将所有字段的后端从数字/整数更改为字符串,但说实话,这感觉不是解决方案。

angular typescript nestjs typeorm angular2-formbuilder
1个回答
0
投票

好吧,所以我基本上发现我可以通过创建自己的装饰器来解决这个问题,该装饰器深受这个 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
    
    }
© www.soinside.com 2019 - 2024. All rights reserved.