Skip to content

Project Image Subdocs

While Multer saves the physical file to the local disk, we still need to save a record of that file in the projectImages array within the project document.

When Multer finishes processing the image, it will populate req.file. We also have access to req.body which contains the text inputs submitted alongside the file (like our alt text and caption). We’ll merge all this information to create our subdocument.

Neo-Retro isometric diagram showing an Express controller taking file metadata from Multer and text metadata from the user form, combining them to form a new subdocument object, and pushing that object into a project document's MongoDB array.

Fig 2: Assembling the Project Image Subdocument

Update your database operations in data/projects.js to create the new injection method:

data/projects.js
// data/projects.js
async addProjectImageToProject(projectId, file, metadata) {
try {
const project = await Project.findById(projectId);
if (!project) return { success: false, errorMessage: "Project not found." };
// If a file was uploaded, embed its metadata!
if (file) {
project.projectImages.push({
originalName: file.originalname,
filename: file.filename,
mimeType: file.mimetype,
size: file.size,
altText: metadata.altText,
caption: metadata.caption,
isFeatured: metadata.isFeatured === "true", // Checkbox cast to boolean
});
}
await project.save();
return { success: true, project };
} catch (error) {
return { success: false, error, errorMessage: "Failed to add projectImage." };
}
}
Professor Solo

Because projectImages is mapped as an array of subdocuments in our Mongoose schema, we can safely .push() an object directly into it, and Mongoose will handle casting the properties specifically. Since we decoupled this from standard project updates, replacing or deleting this specific image later just requires targeting its specific subdocument ID!

The physical files are safely housed on the disk, and MongoDB knows their individual names in the array. Now we can let users modify the metadata (like alt text) for each individual image!