NodeJS

Using sequelize-typescript together with class-transformer

If you use sequelize-typescript together with class-transformer, then you should apply @Exclude to the entire model then @Expose each property that you want to expose, like this:

import { Exclude, Expose } from 'class-transformer';
import { Column, Unique, Model, Table, NotNull, AllowNull, IsEmail, Length, Default } from 'sequelize-typescript';

@Exclude()
@Table
export class User extends Model {
  @Expose()
  @AllowNull(false)
  @NotNull
  @Length({max: 100})
  @Column
  declare name: string;

  @Expose()
  @AllowNull(false)
  @Unique({name: 'email_unique', msg: 'The email is already used.'})
  @IsEmail
  @Length({max: 300})
  @Column
  declare email: string;

  @AllowNull(false)
  @NotNull
  @Length({max: 20})
  @Column
  declare password: string;

  @Default(false)
  @Column
  declare isEmailConfirmed: boolean;
}

If you don’t do like the above, for example:

import { Exclude, Expose } from 'class-transformer';
import { Column, Unique, Model, Table, NotNull, AllowNull, IsEmail, Length, Default } from 'sequelize-typescript';

@Table
export class User extends Model {
  @AllowNull(false)
  @NotNull
  @Length({max: 100})
  @Column
  declare name: string;

  @AllowNull(false)
  @Unique({name: 'email_unique', msg: 'The email is already used.'})
  @IsEmail
  @Length({max: 300})
  @Column
  declare email: string;

  @Exclude()
  @AllowNull(false)
  @NotNull
  @Length({max: 20})
  @Column
  declare password: string;

  @Exclude()
  @Default(false)
  @Column
  declare isEmailConfirmed: boolean;
}

Then the serialized object will contains a lot of strange values:

{
   "dataValues":{
      "id":1,
      "name":"Dipper Pine",
      "email":"dipper_pine@mysteryshack.com",
      "password":"123456",
      "isEmailConfirmed":false,
      "createdAt":"2022-07-22T09:23:11.000Z",
      "updatedAt":"2022-07-22T09:23:11.000Z"
   },
   "_previousDataValues":{
      "id":1,
      "name":"Dipper Pine",
      "email":"dipper_pine@mysteryshack.com",
      "password":"123456",
      "isEmailConfirmed":false,
      "createdAt":"2022-07-22T09:23:11.000Z",
      "updatedAt":"2022-07-22T09:23:11.000Z"
   },
   "uniqno":1,
   "_changed":[
      
   ],
   "_options":{
      "isNewRecord":false,
      "_schema":null,
      "_schemaDelimiter":"",
      "raw":true,
      "attributes":[
         "id",
         "name",
         "email",
         "password",
         "isEmailConfirmed",
         "createdAt",
         "updatedAt"
      ]
   },
   "isNewRecord":false
}

That may be because the sequelize model has many extra attributes. So to make sure serialize works correctly, we have to exclude all attributes and expose only the fields we choose.

Leave a Reply

Your email address will not be published. Required fields are marked *