Home > Mobile >  S3 upload with multer typescript nodejs - Cannot read properties of undefined (reading 'map
S3 upload with multer typescript nodejs - Cannot read properties of undefined (reading 'map

Time:10-06

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
);
  • Related