Home > Back-end >  how to combine nested path in express
how to combine nested path in express

Time:01-09

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

CodePudding user response:

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

  •  Tags:  
  • Related