Search code examples
node.jsreactjsmongodbmulter

How to format Multer image url in MongoDB


I just uploaded images via multer which created a URL path stored in MongoDB. However, the URL comes with a double backslash like so in Postman :

  {
        "_id": "5f9aa0ae9b20ba109857bf39",
        "userId": "5f72df7795ba152db857dc42",
        "name": "Julian Fletcher",
        "email": "[email protected]",
        "imagePath": "\\uploads\\1603969198016\\wifey.JPG",
        "label": "Resume Avatar",
        "createdAt": "2020-10-29T10:59:58.097Z",
        "__v": 0
    }


But when i checked directly in Mongodb compass it appears like so with a single back slash:

{
        "_id": "5f9aa0ae9b20ba109857bf39",
        "userId": "5f72df7795ba152db857dc42",
        "name": "Julian Fletcher",
        "email": "[email protected]",
        "imagePath": "\uploads\1603969198016\wifey.JPG",
        "label": "Resume Avatar",
        "createdAt": "2020-10-29T10:59:58.097Z",
        "__v": 0
    }


This is my challenge: I want to format the double backward slash \ to single forward slash /

Here is my multer configuration :

const express = require('express');
const fs = require('fs');
const path = require('path');
const multer = require('multer');

// multer configuration
const storage = multer.diskStorage({

    destination:function(req,file,cb){
        const uploadsDir = path.join(__dirname,'..','public','uploads',`${Date.now()}`)
        fs.mkdirSync(uploadsDir)
        cb(null,uploadsDir)
    },
    filename:function(req,file,cb){
        cb(null,file.originalname)
    }
})

const uploads=multer({storage})


And here is my controller :


exports.create =  asyncHandler(async (req, res, next) => {
    const remove = path.join(__dirname,'..','public')
    const relPath = req.file.path.replace(remove,'')
    const label = req.body.label;
    const imagePath = relPath
    const  _id = req.params.id;
   

  
    User.findOne({_id: _id}, function(err, photo){
      console.log(photo)
      if (err) {
        console.log('err', err);
        res.status(500).send(err);

        
      } else {
        const newPhoto = new Photo ({
        
            userId:_id,
            name:photo.name,
            email:photo.email,
            imagePath:relPath,
            label:label

    
          });
        
          console.log(`photosDetail before save ${newPhoto}`);
          newPhoto.save(function (err, pool) {
                        if (err) {
                            console.log(err);
                        } else {
                            console.log('image added successfully!');
                            res.send(pool);
                        }
                    });
        
        }
    })
    })

route :

 router.route('/create/:id')
  .post(uploads.single('images'),create)

I have checked different examples but still can't find a solution, would really need help on this one. I think I basically need a way to remove part of the URL "const remove = path.join(__dirname,'..','public')"and change \ to / simulteneously


Solution

  • Your relPath variable needs to change

        const relPath = req.file.path.replace(remove,'')
    

    Change it to the following

    const relPath = req.file.path.replace(remove,'').replace(/\\/g, '/')
    

    This extra replace added at the end will change all backward slashes into forward ones.

    As a side improvement, you can change the replace(remove, '') to a slice

    const skipCharactersCount = path.join(__dirname,'..','public').length
    const relPath = req.file.path.slice(skipCharactersCount)
    

    And since this skipCharactersCount never changes, you can save it as a constant outside of the function to avoid recomputing it every time.

    Thus the replacement code would be like this:

    const skipCharactersCount = path.join(__dirname,'..','public').length;
    exports.create =  asyncHandler(async (req, res, next) => {
        const relPath = req.file.path.slice(skipCharactersCount).replace(/\\/g, '/')
        // rest can stay unchanged