0

I am fairly new to Node JS and Express and I encountered an error while coding. I am uploading an image to s3 from express using multer, and while that has been working fine, I am trying to return the data.Location from the exported S3 uploading function, back to my express router so I can store it in my mongoDB database. Below is the uploadFile, which includes 2 modules, one for multer (upload to server) and one for S3 (upload to S3 bucket).

fileUpload.js

// Multer requirements
const path = require('path')
const multer = require('multer')
const maxSize = 2 * 1024 * 1024

//S3 Requirements
const AWS = require('aws-sdk');
const fs = require('fs');
const { callbackify } = require('util');

require('dotenv').config()

//configuring the AWS environment
AWS.config.update({
  accessKeyId: process.env.AWS_ACCESS_KEY,
  secretAccessKey: process.env.AWS_SECRET_KEY
});

const s3 = new AWS.S3({ apiVersion: '2006-03-01', region: process.env.AWS_BUCKET_REGION });

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, "uploads/");
  },
  filename: function (req, file, cb) {
    cb(null, file.fieldname + "-" + Date.now() + path.extname(file.originalname));
  },
});

const _upload = multer({
  storage: storage,
  fileFilter: (req, file, cb) => {
    if (file.mimetype == "image/png" || file.mimetype == "image/jpg" || file.mimetype == "image/jpeg") {
      cb(null, true);
    } else {
      cb(null, false);
      return cb(new Error('Only .png, .jpg and .jpeg format allowed!'));
    }
  },

  limits: { fileSize: maxSize }
}).single('file');


function imgUpload (req, _path) {
  var params = {
    Bucket: process.env.AWS_BUCKET_NAME,
    Body: fs.createReadStream('./' + _path.toString()),
    Key: "CarLicenses/" + new Date(Date.now()).toLocaleDateString() + "__" + path.basename('./' + req.user._id.toString()) + "__" + new Date().getSeconds()
  };

  s3.upload(params, function (err, data) {
    //handle error
    if (err) {
      console.log("Error", err);
      return err
    }

    //success
    if (data) {
      console.log("Uploaded in:", data.Location);
      return data.Location
    }
  });

}

module.exports._upload = _upload
module.exports.imgUpload = imgUpload

Users.js

const {_upload, imgUpload} = require('../middleware/fileUpload')

router.post("/image",auth, async (req, res) => {
    _upload(req, res, function (err) {
      if (err instanceof multer.MulterError) {
        return res.status(400).send("The file is too large to be uploaded, please try again with a maximum size of 2MB")
      } else if (err) {
        return res.status(400).send("Something went wrong, please try again with the correct file format!")
      }
   
    const file = req.file
    const location = imgUpload(req, file.path)

    console.log(location)
    res.send(file)
    })
  });

As you can see, I'm trying to print the Data.Location that is returned from the imgUpload function in the users.js file, but I keep getting undefined.

Ahmed
  • 21
  • 3
  • Does this answer your question? [How to return the response from an asynchronous call](https://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call) – Tushar Shahi Jul 24 '21 at 17:17
  • @TusharShahi, no, there is no frontend involved whatsoever. So Jquery is not a factor here. This is purely JavaScript – Ahmed Jul 24 '21 at 17:19
  • @Ahmed What does jQuery have to do with it? It's still asynchronous. – Barmar Jul 24 '21 at 17:30
  • @Barmar , can you tell me how to fix the issue? I'm not sure I get what the other post says entirely – Ahmed Jul 24 '21 at 17:37
  • You need to use callback functions, async/await, or promises. Rewriting all your code this way is more than I'm able to do. And you'll learn better if you try to do it yourself. – Barmar Jul 24 '21 at 17:41

0 Answers0