Search code examples
javascriptnode.jsajaxformidable

NodeJS: cannot grab post request text field


I am new to Node JS, so things are not coming easy to me. The scenario is I have input field which will accept multiple files.

<input id="upload-input" type="file" name="uploads[]" multiple="multiple">

in my JS script I grab the the change event of this field, and create a post request to my uploader app which is running in different port using formData and ajax post method

$('#upload-input').on('change', function() {
var files = $(this).get(0).files;
if (files.length > 0) {
    var formData = new FormData();
    formData.append('directory', "path/to/directory");
    for (var i = 0; i < files.length; i++) {
        var file = files[i];
        formData.append('uploads[]', file, file.name);
    }
    $.ajax({
        url: 'https://myurl.com:3000/upload',
        type: 'POST',
        data: formData,
        processData: false,
        contentType: false,
        success: function(data) {
            console.log(data);
        },
    });
}
});

Now the file is sending and in my backend I can upload that using formidable, but the problem is I cannot get the directory value, Here is my code

require('dotenv').load();
var express = require('express');
var app = express();
var path = require('path');
var formidable = require('formidable');
var fs = require('fs');
var session = require('express-session');
app.set('views', __dirname + '/public');
app.use('/uploads', express.static(process.env.USER_UPLOADS))
var cors=require('cors');
app.use(cors({origin:true,credentials: true}));
app.post('/upload', function(req, res) {
    var user_folder = "path/to/directory/";
    var form = new formidable.IncomingForm();
    form.multiples = true;
    form.uploadDir = path.join(__dirname, process.env.USER_UPLOADS + user_folder);
    form.on('file', function(field, file) { fs.rename(file.path, path.join(form.uploadDir, file.name)); });
    form.on('error', function(err) { console.log('An error has occured: \n' + err); });
    form.on('end', function() { res.end('success'); });
    form.parse(req);
});
var server = app.listen(3000, function(){
    console.log('Server listening on port 3000');
});

I tried

console.log(req.body)

but it returns undefined, So how can I get the directory value from my backend?

Thanks in advance.


Solution

  • To fix your issue, I made some changes to your main app's server file i.e. server.js/app.js/index.js anyone that applies to you. See changes below:

    require('dotenv').load();
    var express = require('express');
    var app = express();
    var path = require('path');
    var bodyParser = require('body-parser');
    var formidable = require('formidable');
    var fs = require('fs');
    var session = require('express-session');
    var cors=require('cors');
    
    app.set('views', __dirname + '/public');
    
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: false }));
    app.use(cors({ origin:true, credentials: true }));
    app.use('/uploads', express.static(process.env.USER_UPLOADS));
    
    
    app.post('/upload', function(req, res) {
        var user_folder = "path/to/directory/";
        var form = new formidable.IncomingForm();
        form.multiples = true;
        form.uploadDir = path.join(__dirname, process.env.USER_UPLOADS + user_folder);
        form.on('file', function(field, file) { fs.rename(file.path, path.join(form.uploadDir, file.name)); });
        form.on('error', function(err) { console.log('An error has occured: \n' + err); });
        form.on('end', function() { res.end('success'); });
    
        // Note the changes here
        form.parse(req, (error, fields, files) => {
          console.log(JSON.stringify({
            fields, // { directory: "path/to/directory" }
            files // contains the uploaded files
        }), null, 2);
      });
    });
    
    
    var server = app.listen(3000, function(){
        console.log('Server listening on port 3000');
    });
    

    According to the docs at here, form.parse can take an optional callback function.

    Parses an incoming node.js request containing form data. If cb is provided, all fields and files are collected and passed to the callback:

    form.parse(req, function(err, fields, files) {
      // ... 
    });