'Replace _id to id in NestJs + Typegoose

I use NestJs + Typegoose. How to replace _id to id in NestJs + Typegoose? I didn't find a clear example. I've tried something but without any results.

@modelOptions({
  schemaOptions: {
    collection: 'users',
  },
})
export class UserEntity {
  @prop()
  id?: string;

  @prop({ required: true })
  public email: string;

  @prop({ required: true })
  public password: string;

  @prop({ enum: UserRole, default: UserRole.User, type: String })
  public role: UserRole;

  @prop({ default: null })
  public subscription: string;
}
@Injectable()
export class UsersService {
  constructor(
    @InjectModel(UserEntity) private readonly userModel: ModelType<UserEntity>,
  ) {}

  getOneByEmail(email: string) {
    return from(
      this.userModel
        .findOne({ email })
        .select('-password')
        .lean(),
    );
  }
}


Solution 1:[1]

Another way to update the default _id to id is by overriding the toJSON method in the modelOptions decorator.

@modelOptions({
    schemaOptions: {
        collection: 'Order',
        timestamps: true,
        toJSON: {
            transform: (doc: DocumentType<TicketClass>, ret) => {
                delete ret.__v;
                ret.id = ret._id;
                delete ret._id;
            }
        }
    }
})
@plugin(AutoIncrementSimple, [{ field: 'version' }])
class TicketClass {

    @prop({ required: true })
    public title!: string

    @prop({ required: true })
    public price!: number

    @prop({ default: 1 })
    public version?: number
}


export type TicketDocument = DocumentType<TicketClass>


export const Ticket = getModelForClass(TicketClass);



Solution 2:[2]

i can say it is underlying mongoose behaivor You can send JSON with 'id' instead of '_id' ,a virtual property on all your models is a pretty safe and easy way to do it.

An example:

export const NotesSchema = new Schema({
  title: String,
  description: String,
});

NotesSchema.virtual('id')
    .get(function() {
      return this._id.toHexString();
});

or you can create a toClient() method on your models where you do this. It's also a good place to rename/remove other attributes you don't want to send to the client:

NotesSchema.method('toClient', function() {
    var obj = this.toObject();

    //Rename fields
    obj.id = obj._id;
    delete obj._id;

    return obj;
});

Solution 3:[3]

using typegoose with class-transformer:

import * as mongoose from 'mongoose';
import { Expose, Exclude, Transform } from 'class-transformer';

@Exclude()
// re-implement base Document to allow class-transformer to serialize/deserialize its properties
// This class is needed, otherwise "_id" and "__v" would be excluded from the output
export class DocumentCT {
  @Expose({ name: '_id' })
  // makes sure that when deserializing from a Mongoose Object, ObjectId is serialized into a string
  @Transform((value: any) => {
    if ('value' in value) {
      return value.value instanceof mongoose.Types.ObjectId ? value.value.toHexString() : value.value.toString();
    }

    return 'unknown value';
  })
  public id: string;

  @Expose()
  public createdAt: Date;

  @Expose()
  public updatedAt: Date;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Joel V
Solution 2 har17bar
Solution 3 Guilherme Ramos