1

I am trying to add a file upload feature in my MEAN.js application. I made use of multer, but it places all the files directly in the destination specified at the time of initializing multer. I want to upload files to directories specific to the program for which they are being uploaded (of course create directory dynamically if it doesn't exist). Where should I specify the custom logic of creating directories on the fly and placing files in them.

3 Answers 3

6

I tried a lot of solutions but nothing helped me. Finally I wrote this and it works!


My solution (I am using express 4.13 and multer 1.2):

Imports:

var express = require('express');
var router = express.Router();
var fs = require('fs');
var multer  = require('multer');


Storage variable (see documentation here)

var storage = multer.diskStorage({
    destination: function (req, file, cb) {
        var newDestination = 'uploads/' + req.params.__something;
        var stat = null;
        try {
            stat = fs.statSync(newDestination);
        } catch (err) {
            fs.mkdirSync(newDestination);
        }
        if (stat && !stat.isDirectory()) {
            throw new Error('Directory cannot be created because an inode of a different type exists at "' + dest + '"');
        }       
        cb(null, newDestination);
    }
});


Initializing Multer:

var upload = multer(
    { 
        dest: 'uploads/',
        limits: {
            fieldNameSize: 100,
            fileSize: 60000000
        },
        storage: storage
    }
);


Using it!

router.use("/upload", upload.single("obj"));
router.post('/upload', controllers.upload_file);
Sign up to request clarification or add additional context in comments.

Comments

2

You can't. However, you can move the file to other locations after the file is uploaded. That is probably your best bet. You could make your storage object a module and change the directory dynamically via init

var multer = require('multer'); //  middleware for handling multipart/form-data,
    // Constructor 
    module.exports = function (name) {
        try {
            // Configuring appropriate storage 
            var storage = multer.diskStorage({
                // Absolute path
                destination: function (req, file, callback) {
                    callback(null, './uploads/'+name);
                },
                // Match the field name in the request body
                filename: function (req, file, callback) {
                    callback(null, file.fieldname + '-' + Date.now());
                }
            });
            return storage;
        } catch (ex) {
            console.log("Error :\n"+ex);
        }
    }

3 Comments

How should I specify my api in routes for to be used in angularjs controller?
Could you rephrase your question, I'm kinda confused on what you are trying to ask.
@Punit oh, sorry i guess i was a little to late, looks like you got your answer.
1

I think the best solution to this problem is to use busboy, which let's you store your images in your desired location.

var Busboy = require('busboy');
var fs = require('fs');

app.post('.....',fucntion(req, res, next){
var busboy = new Busboy({ headers: req.headers });
    busboy.on('field', function(fieldname, val) {

      req.body[fieldname] = val;
    });
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
fstream = fs.createWriteStream("path/desiredImageName");
        file.pipe(fstream);
        fstream.on('close', function() {

           file.resume();

     });
})
return req.pipe(busboy);
})

2 Comments

No no no! Multer uses busboy behind the scenes. Multer allows you to configure the file path where you want uploaded files to go!!! Example: var multer = require('multer'); var path = require('path') var storage = multer.diskStorage({ destination: function(req, file, cb) { cb(null, 'uploads/xml'); }, filename: function (req, file, cb) { cb(null, file.fieldname + '_' + Date.now() + path.extname(file.originalname)); } }); let upload = multer({ storage: storage });
Jordy Cuan's answer is better

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.