mongodbmongoosenestjsclass-transformer

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

  • 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.