i have a path like api/courses/materials so there is a roblem that express understand the last ‘materials’ route as a param and i get an error : "CastError: Cast to ObjectId failed for value "materials" (type string) at path "_id" for model "courses""
but if i add additional route param for my last ‘materials’ like api/course/materials/:id it’s will work well
my schemas are:
const courseSchema = new Schema<ICourse>({
title: { type: String, required: true, unique: true },
description: { type: String },
technology: [{ type: String, required: true }],
requiredSkills: [{ type: String }],
duration: { type: Number, required: true },
materials: [{ type: Schema.Types.ObjectId, ref: 'materials' }],
lessons: { type: Number },
testLink: { type: String },
});
const CourseModel = model<ICourse>('courses', courseSchema);
const materialSchema = new Schema<IMaterial>({
content: [
{
_id: { type: String },
stage: { type: Number },
content: [{ type: String }],
isCompleted: Boolean,
},
],
technology: [{ type: String }],
});
const MaterialModel = model<IMaterial>('materials', materialSchema);
and method where i get an error:
const getMaterialsProvider = async () => {
const materials = await MaterialModel.find();
if (!materials) {
throw new Error('materials not found');
}
return materials;
};
How can i combine to route in path like api/courses/materials where ‘materials’ is not converted into param
>Solution :
You did not give the code for your app or router, but it should work if you specify the longer paths before the shorter ones and the ones with a fixed segment name (materials in the 2nd below) before the ones with a parameter in the same place (the 3rd below):
app.use("/api/courses/materials/:id", ...)
.use("/api/courses/materials", ...)
.use("/api/courses/:id", ...)
.use("/api/courses", ...);
The path /api/courses/materials/3 matches all four, so the "closest" match must be placed first. (It’s different if you replace app.use by app.get, where additional segments prevent matching: /api/courses/materials/3 would then match only the first.)