Search code examples
node.jsexpresspostmanmultipartform-datamulter

How to upload image files in Postman and echo back the same image using Express and Multer


I am trying to upload a product using postman and anytime I submit; it sends back all the data with the image undefined as shown in this screenshot:

Postman output

My controller file:

const gameRepository = require("../routes/repository")

exports.createGame = async (req, res, next) => {
    try {
        const PORT = 8000;
        const hostname = req.hostname;
        const url = req.protocol + '://' + hostname + ':' + PORT + req.path;

        const payload = ({
            name: req.body.name,
            price: req.body.price,
            category: req.body.category,
            gameIsNew: req.body.gameIsNew,
            topPrice: req.body.topPrice,
            isVerOrient: req.body.IsVerOrient,
            description: req.body.description,
            image: url + '/imgs/' + req.path
        });          
        
        let eachGame = await gameRepository.createGame({
            ...payload
        });

        console.log(req.body)

        res.status(200).json({
            status: true,
            data: eachGame,
        })
    } catch (err) {
        console.log(err)
        res.status(500).json({
            error: err,
            status: false,
        })
    }
}

repository.js:

const Game = require("../models/gameModel");

exports.games = async () => {
    const games = await Game.find();
    return games;
}

exports.gameById = async id => {
    const game = await Game.findById(id);
    return game;
}

exports.createGame = async payload => {
    const newGame = await Game.create(payload);
    return newGame;
}

exports.removeGame = async id => {
    const game = await Game.findById(id);
    return game;
}

Multer.js:


const multer = require("multer");
const path = require("path");

// checking for file type
const MIME_TYPES = {
    'imgs/jpg': 'jpg',
    'imgs/jpeg': 'jpeg',
    'imgs/png': 'png'
}

// Image Upload
const storage = multer.diskStorage({
    destination: (req, file, cb ) => {
        cb(null, path.join('../imgs'));
    },
    filename: (req, file, cb) => {
        const name = file.originalname.split('').join(__);
        const extension = MIME_TYPES[file.mimetype];
        cb(null, name + new Date().toISOString() + '.' + extension);
    }
});

module.exports = multer({
    storage: storage,
    limits: {
        fileSize: 1024 * 1024 * 6
    },
})

I am not sure about where I went wrong, that is why I need an external eye to help locate where the fault is coming from.

I have a feeling that I need to use body-parser or navigate into the image folder correctly, or multi-part form, I am not sure.


Solution

  • after many try and fail I finally figured it out. turns out it has compatibility issues depending on your OS.

    I use windows 10 and this resolved the issue for me

    Here is my working code:

    multer.js

    
    const multer = require("multer");
    const path = require("path");
    
    
    // checking for file type
    const MIME_TYPES = {
        'image/jpg': 'jpg',
        'image/jpeg': 'jpeg',
        'image/png': 'png'
    }
    
    // Image Upload
    const storage = multer.diskStorage({
        destination: (req, file, cb ) => {
          cb(null, ('storage/imgs/'));
        },
        filename: (req, file, cb) => {
            const extension = MIME_TYPES[file.mimetype];
        
        // I added the colons in the date of my image with the hyphen 
            cb(null, `${new Date().toISOString().replace(/:/g,'-')}.${extension}`);
        }
    });
    
    module.exports = multer({
        storage: storage
    })
    
    

    In my controller.js

    
    const gameRepository = require("../routes/repository");
    
    exports.createGame = async (req, res, next) => {
      try {
        const payload = {
          name: req.body.name,
          price: req.body.price,
          category: req.body.category,
          gameIsNew: req.body.gameIsNew,
          topPrice: req.body.topPrice,
          isVerOrient: req.body.IsVerOrient,
          description: req.body.description,
          image: req.file.filename,
        };
    
        let eachGame = await gameRepository.createGame({
          ...payload,
        });
        
        res.status(200).json({
          status: true,
          data: eachGame,
        });
      } catch (err) {
        console.log(err);
        res.status(500).json({
          error: err,
          status: false,
        });
      }
    };
    
    exports.getGames = async (req, res) => {
      try {
        let games = await gameRepository.games();
        res.status(200).json({
          status: true,
          data: games,
        });
      } catch (err) {
        console.log(err);
        res.status(500).json({
          error: err,
          status: false,
        });
      }
    };
    
    exports.getGameById = async (req, res) => {
      try {
        let id = req.params.id;
        let gameDetails = await gameRepository.gameById(id);
        req.req.status(200).json({
          status: true,
          data: gameDetails,
        });
      } catch (err) {
        res.status(500).json({
          status: false,
          error: err,
        });
      }
    };
    
    exports.removeGame = async (req, res) => {
      try {
        let id = req.params.id;
        let gameDetails = await gameRepository.removeGame(id);
        res.status(200).json({
          status: true,
          data: gameDetails,
        });
      } catch (err) {
        res.status(500).json({
          status: false,
          data: err,
        });
      }
    };
    
    

    :

    Postman output

    Thanks to this great community.