'How to have class-transform converting properly the _id of a mongoDb class?
I've the following mongoDb class:
@Schema()
export class Poker {
@Transform(({ value }) => value.toString())
_id: ObjectId;
@Prop()
title: string;
@Prop({ type: mongoose.Schema.Types.ObjectId, ref: User.name })
@Type(() => User)
author: User;
}
which I return, transformed by class-transform
in a NestJs server.
It get transformed by an interceptor:
@Get()
@UseGuards(JwtAuthenticationGuard)
@UseInterceptors(MongooseClassSerializerInterceptor(Poker))
async findAll(@Req() req: RequestWithUser) {
return this.pokersService.findAll(req.user);
}
I'm not the author of the interceptor, but here is how it is implemented:
function MongooseClassSerializerInterceptor(
classToIntercept: Type,
): typeof ClassSerializerInterceptor {
return class Interceptor extends ClassSerializerInterceptor {
private changePlainObjectToClass(document: PlainLiteralObject) {
if (!(document instanceof Document)) {
return document;
}
return plainToClass(classToIntercept, document.toJSON());
}
private prepareResponse(
response: PlainLiteralObject | PlainLiteralObject[],
) {
if (Array.isArray(response)) {
return response.map(this.changePlainObjectToClass);
}
return this.changePlainObjectToClass(response);
}
serialize(
response: PlainLiteralObject | PlainLiteralObject[],
options: ClassTransformOptions,
) {
return super.serialize(this.prepareResponse(response), options);
}
};
}
export default MongooseClassSerializerInterceptor;
The problem I'm having, is that when I do a console.log of the return of my controller, I get this:
[
{
_id: new ObjectId("61f030a9527e209d8cad179b"),
author: {
_id: new ObjectId("61f03085527e209d8cad1793"),
password: '--------------------------',
name: '----------',
email: '-------------',
__v: 0
},
title: 'Wonderfull first poker2',
__v: 0
}
]
but I get this returned:
[
{
"_id": "61f5149643092051ba048c6e",
"author": {
"_id": "61f5149643092051ba048c6f",
"name": "----------",
"email": "-------------",
"__v": 0
},
"title": "Wonderfull first poker2",
"__v": 0
}
]
If you check the id, it's not at all the same. Then the client will ask some data for this ID and receive nothing.
Any idea what am I missing?
Also, everytime I make a Get request, I receive a different value back.
Solution 1:[1]
Try using this for _id:
@Transform(params => params.obj._id)
Or this for a more general case:
@Transform(({ key, obj }) => obj[key])
Stuck with the same problem, solved it this way. params.obj is an original object. Unfortunately, I don't know, why class-transformer doesn't define _id correctly by default.
Solution 2:[2]
If you want to make a change to the schema directly and you just use mongoose, you have a schema like below.
const mongoose = require('mongoose')
const mySchema = new mongoose.Schema({
field: String
}, {
toJSON: {
transform(doc, ret) {
ret.id = ret._id;
delete ret._id;
delete ret.__v;
}
}
})
module.exports = mongoose.model("MySchema", mySchema)
But if you are using @nestjs/mongoose
you should have usage like below.
import { Document } from 'mongoose';
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
export type MyDocument = MyClass & Document;
@Schema({
toJSON: {
transform(doc, ret) {
ret.id = ret._id;
delete ret._id;
delete ret.__v;
},
},
})
export class MyClass {
@Prop()
field: string;
}
export const MySchema = SchemaFactory.createForClass(MyClass);
Recall that in the first example, the first parameter of the new mongoose.Schema
function is the schema object and the second parameter is the schema options. So, the class schema object that @Schema
decarator has, the parameters it will include are Schema options!
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 | OcelotJungle |
Solution 2 | Sami Salih ?brahimba? |