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
I defined virtual field for reportedUser and values get populated as expected
the error you are getting is because you are trying to cast string to objectID
just match the userId directly like below –