Problem with uploading nodejs file using formidable

1
//probando subida de imagen

router.post('/uploadImage', (request, response, next) => {
    let formidable = require('formidable');
    var form = new formidable.IncomingForm();

    form.uploadDir = "../imagenes/";
    form.keepExtensions = true;
    form.maxFieldsSize = 10 * 1024 * 1024; //10MB
    form.multiples = true;

    form.parse(request, (err, fields, files) => {

        if (err) {
            response.json({
                message: 'error al subir la imagen',
                data: {}
            });
        }

        var  arrayOfFiles = files[""];

        if (arrayOfFiles.length > 0) {
            var fileNames = [];
            arrayOfFiles.forEach((eachFile) => {
                fileNames.push(eachFile.path)
            });

            response.json({
                message: 'imagen subida correctamente !!',
                //data = fileNames,
                //numImagenes = fileNames.length
            })
        }

        else {
            response.json({
                message: 'No hay ninguna imagen seleccionada para subir .. ',
                data: {},
               // numImagenes: 0
            })
        }
    })

})

Error output:

  

TypeError: Can not read property 'length' of undefined

I do not understand that error, it is very rare that you tell me that you do not know a property as common as a 'length' of an array, does anyone know how to tell me what this strange error is?

  

With the adaptation, it returns that it is empty:

PS: so that I did not miss these two variables, I had to initialize them in the following way, I do not know if it will be correct =

  const data = []; //variable para la respuesta al Front
    const  filesPath = '' //variable donde guardaremos todos los path de los archivos subidos

The adapted code currently used:

router.post('/uploadImage', (request, response) => {
    const form = new formidable.IncomingForm()
    const address = path.dirname(__filename).split('/')
    address.pop()

    form.uploadDir = "../imagenes/";
    form.keepExtensions = true; //mantener las extensiones
    form.maxFieldsSize = 10 * 1024 * 1024; //10MB
    form.multiples = true; //multiples archivos

    form.parse(request, (err, fields, files) => {

        var data = []; //variable para la respuesta al Front
        var  filesPath = '' //variable donde guardaremos todos los path de los archivos subidos

        if (err) {
            response.json ( {
                message: 'error al subir la imagen',
                data: []
            })
        }

        if (files.length > 0) {
            filesPath = files.map(file => file.path); //Recorremos el array de objetos y devolvemos uno nuevo con solo los path de los archivos subidos.
            //se puede devolver los nombres haciendo esto files.map(file => file.name)
            response.json ( {
                message: 'imagen subida correctamente !!',
                data : filesPath,
                numImagenes : filesPath.length
            })
        } else {
            response.json ( {
                message: 'No hay ninguna imagen seleccionada para subir .. ',
                data: [],
                numImagenes: 0
            })
        }
    })

    response.json(data)
})
    
asked by jose angel 07.12.2018 в 19:41
source

1 answer

0

I have never worked with the 'formidable' module to upload files but I have been reviewing the Api and the documentation and it seems that it is not difficult to work with.

You have to bear in mind that the form that you put in the Front (Angular) to upload the files must have this configuration:

test.html

 <form action="/uploadImage" enctype="multipart/form-data" method="post">
  <input type="text" name="title">
  <input type="file" name="upload" multiple="multiple">
  <input type="submit" value="Upload">
 </form>

Note that I modified the 'action' attribute by the express endpoint.

From here you have to work with the Back to manage the files. I enclose the code so you can try it and confirm if it is correct:

test.js

const formidable = require('formidable')
const path = require('path')
const express = require('express')
const app = express()

app.get('/', (req, res) => {
    res.sendFile(__dirname + '/test.html'); //Formulario de arriba (es para probar)
})

app.post('/uploadImage', (request, response) => {
    const form = new formidable.IncomingForm()
    const address = path.dirname(__filename).split('/')
    address.pop()

    form.uploadDir = './imagenes/'; //path donde guardaras la imagines
    form.keepExtensions = true; //mantener las extensiones
    form.maxFieldsSize = 10 * 1024 * 1024; //10MB
    form.multiples = true; //multiples archivos

    form.parse(request, (err, fields, files) => {
        if (err) {
            response.json({
                message: 'error al subir la imagen',
                data: []
            })
        }

        const { upload } = files //Hacemos Destructuring, por lo que equivale a 'const upload = files.upload'
        let data 

        if (upload) { //Si existe archivo subido o no
            let filesPath

            if (Array.isArray(upload)) { //Si se han subido mas de un archivo, es decir, si es un Array de archivos
                filesPath = upload.map(file => file.path) 
            } else {
                filesPath = upload.path
            }

            data = {
                message: 'imagen subida correctamente !!',
                data: filesPath, //Devolvemos una o la lista de rutas de los archivos
                numImagenes: upload.length //Devolvemos la cantidad de archivos
            }
        } else {
            data = {
                message: 'No hay ninguna imagen seleccionada para subir .. ',
                data: [],
                numImagenes: 0
            }
        }

        response.json(data)
    })
    })
   app.listen(4000, () => console.log("Server"))
    
answered by 07.12.2018 в 23:29