A question regarding multer middleware from project "file metadata microservice"

Hi I am have completed FreeCodeCamp’s File-metadata microservice project . But after fulfilling the user stories, I wanted to try implementing the multiple files uploading function of multer. However I am stuck at understanding one particular phenomenon.

I observed something: If I have two multer’s upload functions (namely upload.single() and upload.array()) mounted to the same path (’/’ in this case), the second one won’t work.

Here is my app.js.

var multer = require('multer')
var express = require('express')
var path = require('path')
var bodyParser = require('body-parser')
var app = express()
var port = 3000
var result = new Array()

app.use(bodyParser.json())

app.use(express.static(path.join(__dirname, 'public')));

app.get('/', function(req, res){
    res.sendFile(path.join(__dirname, 'views/index.html'));
})

/*----------------------------Multer--------------------------------*/

var storage = multer.diskStorage({
    destination: function(req, file, callback){
        callback(null, 'storage/');
    },
    filename: function(req, file, callback){
        callback(null, new Date() + "-" + file.fieldname)
    }
});

var upload = multer({storage: storage})


app.post('/', upload.array('files', 4), function(req, res){
    console.log(req.files);

    for(var i = 0; i < req.files.length; i++){
        result[i] = { "name": "item " + i,"size" : req.files[i].size }
    } 

    res.redirect('/collectionsize')
})

app.post('/', upload.single('myFile'), function(req, res){
    console.log(req.file);
    result = { "size" : req.file.size }
    res.redirect('/filesize');
}) 

app.get('/filesize', function(req, res){
    res.json(result)
})

app.get('/collectionsize', function(req, res){
    
    res.json(result)
})

/*----------------------------Multer--------------------------------*/

var server = app.listen(process.env.PORT || port, function(){
    console.log("Server listening on port " + ((process.env.PORT)? process.env.PORT : port))
})

Here is my index.html

<!DOCTYPE html>
<!-- Name: Darius He Xing-->

<html>

<head>
<title>File Metadata Project</title>
</head>

<body>

<form id='myForm' name='myForm' enctype='multipart/form-data' method='post'>
    <input type="file" name="myFile" />
    <input id="myButton" type="submit" name="submit" >
</form>

<form id='Form2' name='Form2' enctype='multipart/form-data' method='post'>
    <input type="file" name="files" />
    <input type="file" name="files" />
    <input id="myButton" type="submit" name="submit" >
</form>

<p>This is a mini web app that tells you how big your uploaded file is.</p>

</body>
</html>

How is it so? Any idea how I can remedy this?

Well you have two resources that can located on the same URL. Its kind of like having two different files in the same directory with the same name. So I guess express just ignores the second time you try to register a callback to the same url. What are you trying to do exactly?

I couldn’t find any documentation for it, but I believe Express will just go down your routes and use the first one that matches the call.

Thank you so much for the response! I am simply getting my hands more dirty by trying to make use of the given functionalities provided by multer middleware.

So as in the index.html, First form segment myform is to implement multer’s upload.single() function, the second form Form2 is to implement the multer’s upload.array() function. But since these two forms are in the same page, I could therefore only use the same path / for the 2 callbacks.

You can declare a specific URL for each form using the action attribute of the form tag. Check out this link for more info on form and all its attributes.

<form id='myForm' name='myForm' enctype='multipart/form-data' method='post' action='/single'>
   ...
</form>

<form id='Form2' name='Form2' enctype='multipart/form-data' method='post' action='/multiple'>
    ...
</form>

Then in express you can have two routes:

app.post('/multiple', upload.array('files', 4), function(req, res){
    console.log(req.files);

    for(var i = 0; i < req.files.length; i++){
        result[i] = { "name": "item " + i,"size" : req.files[i].size }
    } 

    res.redirect('/collectionsize')
})

app.post('/single', upload.single('myFile'), function(req, res){
    console.log(req.file);
    result = { "size" : req.file.size }
    res.redirect('/filesize');
})

OMG, that worked impeccably great!
What I could think of to implement my idea was far more complicated.
Thank you so much! that saved me tons of time and effort wasted on the wrong approach.