0

I'm currently trying to add formidable so I can handle forms that also include files (images, actually) that are uploaded, I've read comments saying that both modules can't work together butthis comment here shows them both working together.

This is the code where I try to handle the form

router.post("/", middleware.isLoggedIn, function(req, res){

var form = new formidable.IncomingForm();
console.log(form);
form.uploadDir = "../img";
form.keepExtensions = true;
form.parse(req, function(err, fields, files) {
    if(err){
        console.log(err);
    }
   console.log(fields);
   console.log(files);
});

And these are all the dependencies I have

var express = require("express"),
app = express(),
bodyParser = require("body-parser"),
mongo = require("mongoose"),
User = require("./models/user"),
passport = require("passport"),
passportLocal = require("passport-local"),
indexRoutes = require("./routes/index"),
commentRoutes = require("./routes/comments"),
picRoutes = require("./routes/pictures"),
methodOverride = require("method-override"),
formidable = require("formidable");
app.use(bodyParser.urlencoded({extended: true}));
app.set("view engine", "ejs");
app.use(express.static(__dirname + "/public"));
app.use(methodOverride("_method"));
mongo.connect("mongodb://localhost/yelp_camp");
app.use(passport.initialize());
app.use(passport.session());
passport.use(new passportLocal(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

This is what's currently being shown when I log form before parsing

IncomingForm {
domain: null,
_events: {},
_eventsCount: 0,
_maxListeners: undefined,
error: null,
ended: false,
maxFields: 1000,
maxFieldsSize: 2097152,
keepExtensions: false,
uploadDir: '/tmp',
encoding: 'utf-8',
headers: null,
type: null,
hash: false,
multiples: false,
bytesReceived: null,
bytesExpected: null,
_parser: null,
_flushing: 0,
_fieldsSize: 0,
openedFiles: [] }

Form:

    <div class="container">
    <div class="row">
        <div class="form">
            <h1>Add new campground</h1>
            <form action="/pictures" method="post">
                <div class="form-group">
                    <label for="name">Give a name to your picture</label>
                    <input class="form-control" id="name" type="text" name="campground[name]" placeholder="Name" autofocus required>
                </div>
                <div class="form-group" id="linkDiv">
                    <label for="link">Paste a direct link to your image</label>
                    <input type="radio" id="link" name="method" value="link"><input class="form-control" id="fileLink" type="text" name="campground[image]" placeholder="Image URL"></input></input>
                </div>
                <div class="form-group" id="uploadDiv">
                    <label for="upload">Or upload the picture</label>
                    <input type="radio" id="upload" name="method" value="upload"><input class="form-control" id="fileUpload" type="file" name="image" value="Upload file" disabled></input></input>
                </div>
                <div class="form-group">
                    <label for="description">Add a description to your picture</label>
                    <input class="form-control" id="description" type="text" name="campground[description]" placeholder="Description">
                </div>
                <div class="form-group">
                    <button class="btn btn-lg btn-primary btn-block">Submit!</button>
                </div>
            </form>
        </div>
    </div>
</div>

But after that parse doesn't seem to run, neither of the console.log is shown

Community
  • 1
  • 1
Danyx
  • 574
  • 7
  • 34

1 Answers1

0

both modules [body-parser and formidable] can't work together

But works :) I use them together.

On server-side

// app.js
app.use(require('body-parser').urlencoded({extended: false})); 

// inside upload-router function (req, res, next)
var formidable = require ('formidable');
var fs = require('fs');

var form = new formidable.IncomingForm();
form.uploadDir = '/public/temp/';

form.parse(req, function(err, fields, files) {
    var file = files.file;
    var target = '/public/temp/' + file.name;
    fs.rename(file.path, target, function (err) {   
            if (err) 
                return next(err);
            ...
        });
    });
}

On client

<form id = "upload-form" method = "post" >
    <input type="file" id = "upload-input" name = "file" required />
    <input type = "button" onclick = "ajax...">Upload</input>
</form>
...
$.ajax({
    type: 'POST',
    url: '/upload',
    data: new FormData($('#upload-form')[0]),
    enctype: 'multipart/form-data',
    processData: false,
    contentType: false,
    dataType: 'json',
    success: function (data) {
        ...
    }
});
Aikon Mogwai
  • 4,954
  • 2
  • 18
  • 31
  • Is it necessary to add the enctype for it to work? Aside from not having fs and urlencoded extended being true I don't see differences between our codes, are these the problem? – Danyx Jul 22 '16 at 21:35
  • I tried change enctype and urlencoded. No problem, result is ok. Try open browser console, send file and make sure that file sent by client. – Aikon Mogwai Jul 22 '16 at 21:58
  • Is Ajax necessary when using formidable? I've only been using HTML forms, updated my post so you can see. PS: sorry for the late response. – Danyx Aug 08 '16 at 14:31
  • Nope. It's can be html form also. – Aikon Mogwai Aug 08 '16 at 14:34
  • 1
    You didn't set enctype. Put enctype: 'multipart/form-data' as an attribute of form in order to make formidable() understand that your form has file information. – MarcosCunhaLima Jun 26 '17 at 20:06