I have created a route for uploading files to an S3 bucket, which is working perfectly. However, when I try and add it into my Accommodation controller with additional logic it is causing the error Cannot read properties of undefined (reading 'map')
. I am using the exact same request in postman for each route.
Can anyone spot why this is happening?
My original logic for the upload controller:
import { Request, Response } from "express";
import catchBlock from "../utils/catchBlock";
import { s3Uploadv2 } from "../utils/s3Service";
const UploadController = {
Upload: async (req: Request, res: Response) => {
const files = req.files as Express.Multer.File[];
try {
const results = await s3Uploadv2(files);
res.send({ success: "successful", results });
} catch (e: unknown) {
catchBlock(e, res);
}
},
};
export default UploadController;
My accommodation upload:
UploadImages: async (req: Request, res: Response) => {
const accommodationId = req.params.id;
const accommodation = await accommodationSchema.findOne({
_id: accommodationId,
});
const files = req.files as Express.Multer.File[];
try {
const results = await s3Uploadv2(files);
console.log(results);
if (accommodation) {
results.forEach((file) => accommodation.photos.push(file.Location));
await accommodation.save();
res.send({ success: "successful", accommodation });
} else {
res.status(400).send("No such accommodation");
}
res.send({ success: "successful", results });
} catch (e: unknown) {
catchBlock(e, res);
}
},
S3 service:
import { S3 } from "aws-sdk";
import { v4 as uuid } from "uuid";
export interface Param {
Bucket: string;
Key: string;
Body: Buffer;
}
export const s3Uploadv2 = async (files: Express.Multer.File[]) => {
const s3 = new S3();
const params: Param[] = files.map((file) => {
return {
Bucket: process.env.AWS_BUCKET_NAME,
Key: `uploads/${uuid()}-${file.originalname}`,
Body: file.buffer,
};
});
const results = await Promise.all(
params.map((param) => s3.upload(param).promise())
);
return results;
};
Multer service:
import multer, { FileFilterCallback, MulterError } from "multer";
import { Request } from "express";
const storage = multer.memoryStorage();
const fileFilter = (
req: Request,
file: Express.Multer.File,
cb: FileFilterCallback
) => {
if (file.mimetype.split("/")[0] === "image") {
cb(null, true);
} else {
cb(new MulterError("LIMIT_UNEXPECTED_FILE"));
}
};
export const upload = multer({
storage,
fileFilter,
limits: { fileSize: 1000000, files: 5 },
});
Accommodation Route:
import express from "express";
import AccommodationController from "../controllers/accommodation";
const accommodationRouter = express.Router();
accommodationRouter.get("/", AccommodationController.All);
accommodationRouter.post(
"/create",
AccommodationController.CreateAccommodation
);
accommodationRouter.get(
"/users-accommodation",
AccommodationController.UsersAccommodation
);
accommodationRouter.post("/delete/:id", AccommodationController.Delete);
accommodationRouter.post("/upload/:id", AccommodationController.UploadImages);
export default accommodationRouter;
Upload Route:
import express from "express";
import UploadController from "../controllers/upload";
import { upload } from "../utils/multer";
const uploadRouter = express.Router();
uploadRouter.post("/", upload.array("file", 5), UploadController.Upload);
export default uploadRouter;
CodePudding user response:
realised my mistake was not putting my upload middleware on the accommodation route.
changed this:
accommodationRouter.post("/upload/:id", AccommodationController.UploadImages);
to this:
accommodationRouter.post(
"/upload/:id",
upload.array("file", 5),
AccommodationController.UploadImages
);