skip to Main Content

I have to work on an already developed backend where I need to add a few endpoints. In the user model, they have used userId a custom-generated ID (Cannot change now), but for my API, I want to user populate data with my return response, since the system uses userId instead of _id, I can’t map the populate correctly. So how do I populate data?

User Model

export const userSchema: Schema<User> = new Schema<User>({
  userId: { type: String, required: true },
  email: { type: String, required: true, unique: true },

});

const UserModel = mongoose.model<User>("User", userSchema);
export default UserModel;

My Report Model

// Schema for the Report model
const reportSchema: Schema<IReport> = new Schema({
  reportedUserId: { type: String, ref: "User" },
  reporterId: { type: String, required: true, ref: "User" },
  reason: { type: String, required: true },
  createdAt: { type: Date, default: Date.now },
});

export const Report = mongoose.model<IReport>("Report", reportSchema);

Get Report Query

const reports = await Report.find(query)
    .populate({
          path: "reportedUserId",
          select: "userId email name nickname",
          model: UserModel,
          options: { localField: "reportedUserId", foreignField: "userId" },
        })
      
    .skip((page - 1) * limit)
    .limit(limit);
return reports;

Error

Error fetching reports: CastError: Cast to ObjectId failed for value "92e15ec7-f34d-4bd3-9b9e-95ba3fa99999" (type string) at path "_id" for model "User"
    at SchemaObjectId.cast (XXXnode_modulesmongooselibschemaobjectId.js:250:11)
    at SchemaType.applySetters (XXXnode_modulesmongooselibschemaType.js:1221:12)
    at SchemaType.castForQuery (XXXnode_modulesmongooselibschemaType.js:1636:17)
    at XXXnode_modulesmongooselibschemaType.js:1597:18
    at Array.map (<anonymous>)
    at SchemaObjectId.handle$in (XXXnode_modulesmongooselibschemaType.js:1593:14)
    at SchemaType.castForQuery (XXXnode_modulesmongooselibschemaType.js:1632:20)
    at cast (XXXnode_modulesmongooselibcast.js:352:39)
    at Query.cast (XXXnode_modulesmongooselibquery.js:4778:12)
    at Query._castConditions (XXXnode_modulesmongooselibquery.js:2199:10)
    at model.Query._find (XXXnode_modulesmongooselibquery.js:2225:8)
    at model.Query.exec (XXXnode_modulesmongooselibquery.js:4322:80)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  stringValue: '"92e15ec7-f34d-4bd3-9b9e-95ba3fa99999"',
  messageFormat: undefined,
  kind: 'ObjectId',
  value: '92e15ec7-f34d-4bd3-9b9e-95ba3fa99999',
  path: '_id',
  reason: BSONError: input must be a 24 character hex string, 12 byte Uint8Array, or an integer
      at new ObjectId (XXXnode_modulesbsonlibbson.cjs:2251:23)
      at castObjectId (XXXnode_modulesmongooselibcastobjectid.js:25:12)
      at SchemaObjectId.cast (XXXnode_modulesmongooselibschemaobjectId.js:248:12)
      at SchemaType.applySetters (XXXnode_modulesmongooselibschemaType.js:1221:12)
      at SchemaType.castForQuery (XXXnode_modulesmongooselibschemaType.js:1636:17)
      at XXXnode_modulesmongooselibschemaType.js:1597:18
      at Array.map (<anonymous>)
      at SchemaObjectId.handle$in (XXXnode_modulesmongooselibschemaType.js:1593:14)
      at SchemaType.castForQuery (XXXnode_modulesmongooselibschemaType.js:1632:20)
      at cast (XXXnode_modulesmongooselibcast.js:352:39)
      at Query.cast (XXXnode_modulesmongooselibquery.js:4778:12)
      at Query._castConditions (XXXnode_modulesmongooselibquery.js:2199:10)
      at model.Query._find (XXXnode_modulesmongooselibquery.js:2225:8)
      at model.Query.exec (XXXnode_modulesmongooselibquery.js:4322:80)
      at process.processTicksAndRejections (node:internal/process/task_queues:95:5),
  valueType: 'string',
  model: Model { User }
}

I tried setting the type of reportedUserId and reporterId to the mongoose.Types.ObjectId and use _id, then data populating without an issue, but I cannot change the User table now or frontend data passing auth token logics.

2

Answers


  1. Chosen as BEST ANSWER

    I defined virtual field for reportedUser and values get populated as expected

    reportSchema.virtual("reportedUser", {
      ref: UserModel,
      localField: "reportedUserId",
      foreignField: "userId",
      justOne: true,
    });
    
    const reports = await Report.find(query)
        .populate({
              path: "reportedUser",
              select: "userId email name nickname",
            })
        .skip((page - 1) * limit)
        .limit(limit);
    return reports;
    

  2. the error you are getting is because you are trying to cast string to objectID

    just match the userId directly like below –

    const reports = await Report.find({})
      .populate({
        path: "reportedUserId",
        select: "userId email name nickname",
        model: UserModel,
        match: { userId: '92e15ec7-f34d-4bd3-9b9e-95ba3fa99999' }, 
      })
      .skip((page - 1) * limit)
      .limit(limit);
    
    return reports;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search