简体   繁体   中英

Return ONLY selected fields within a TypeORM find request

I'm struggling in returning only selected fields in my TypeORM find request.

Assuming the following request


const data = await AppDataSource.manager.find(User, {
    select: {
      id: true,
      hash: true,
      firstname: true,
      lastname: false,
    },
    take: 10, // Just here to shrink dataset
  });

The script works pretty well excepted that it return every field of my model, with default value initialized.

[
  User {
    prefix: 'usr',
    hash: 'usr_835b0ad2-XXXXXX',
    email: undefined,
    accountValidated: false,
    role: 'free',
    myKeyOne: true,
    myKeyTwo: false,
    gender: 'unspecified',
    lastConnexion: 2023-01-19T10:11:02.733Z,
    pendingDeletion: false,
    deletionDate: undefined,
    firstname: 'Clément',
    lastname: undefined,
    password: undefined,
    facebookId: undefined,
    googleId: undefined,
    id: 158
  },
  ...
]

Of course, it's not usable as it, because I have extensive relations, and thus the payload would be extremely heavy.

Are you aware of a method / a way to remove all unnecessary fields? ie I'm expecting

[
 User {
    id: 124,
    hash: 'urs_XXXX',
    firstname: 'Clément',
 },
 ...
] 

In older versions of typeorm I think you need to select with an array of strings, try:

select: ["id", "hash", "firstname"],

See this older version of the docs: https://github.com/typeorm/typeorm/blob/bc60dd559ba42af083ddea17f01205c78c83c7e0/docs/find-options.md

After hours of researches I've finally found out why it behaved like this.

TypeORM relies on class definitions and typescript so... if you have typescript default values OR if you have rewrite your constructor, all the "default" properties are injected.

Assuming a User model

You should not do

@Entity({ name: 'users' })
class User {
  
  @Column()
  firstname?: string;

  @Column({ nullable: true })
  lastname?: string;

  @Column({ unique: true, nullable: false })
  email!: string;

  @Column({ name: 'account_validated', nullable: false})
  accountValidated?: boolean = false

  //Your other fields...
}

You should do

@Entity({ name: 'users' })
class User {
  
  @Column()
  firstname?: string;

  @Column({ nullable: true })
  lastname?: string;

  @Column({ unique: true, nullable: false })
  email!: string;

  // Use default argument of the decorator
  @Column({ name: 'account_validated', nullable: false, default: false})
  accountValidated?: boolean

  //Your other fields...
}

And if you need in some way to init a default, then create a public static method which return the Entity instead of using the constructor.

@Entity({ name: 'users' })
class User {
  //...fields 
  public static init(...params): User {
    let _user = new User()
    //...populate your object
    return _user

  }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM