how to combine nested path in express

0

Issue

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

Answered By – Heiko Theißen

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave A Reply

Your email address will not be published.

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More