Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

how to combine nested path in express

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

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading