Typeerror: Cannot read Property 'filename' of Undefined

Asked

Viewed 1,466 times

3

I intend to store the file in the folder uploads and secure in the bank the name of the file. The console.log() show me this:

{theBook: undefined, cover: undefined}

Stores the image in the folder uploads but don’t file the name in the comic book, coming as Undefined.

'Cause I’m getting this result?:

Typeerror: Cannot read Property 'filename' of Undefined


My file:

eBook.js

const express = require("express");
const router = express.Router();
const mongoose = require("mongoose");
const User = mongoose.model('users');
const requireDir = require('require-dir');
requireDir('../models');
const eBook = mongoose.model('books');
const multer = require('multer');
const uploadConfig = require('../config/upload');

const upload = multer(uploadConfig);
var eBookUpload = upload.fields([
{ name: 'cover', maxCount: 1 }, 
{ name: 'theBook', maxCount: 1 }
]);

router.post('/add', eBookUpload, async (req, res, next) => {
    var erros = []

    if(!req.body.title || typeof req.body.title == undefined || req.body.title == null){
        erros.push({texto: "Título inválido"})
    }

    if(!req.body.author || typeof req.body.author == undefined || req.body.author == null){
        erros.push({texto: "Autor inválido"})
    }

    if(erros.length > 0){
        res.render("pages/ebooks/create", {erros: erros})
    }else{
        const filename = req.file.filename;
        const newBook = {
            title: req.body.title,
            author: req.body.author,
            genre: req.body.genre,
            publisher: req.body.publisher,
            edition: req.body.edition,
            isbn: req.body.isbn,
            pages: req.body.pages,
            theBook: filename,
            cover: filename,
            type: req.body.type,

        }
        new eBook(newBook).save().then(function(){
            req.flash("success_msg", "eBook adicionado com sucesso!")
            res.redirect("/ebook/galeria")
            console.log(newBook)
        }).catch(function(err){
            console.log(err)
            req.flash("error_msg", "Houve um erro ao salvar o eBook! Tente novamente")
            res.redirect("/ebook/galerias")
        })
    }
});
  • According to your code the expected console.log is not { theBook: undefined,
 cover: undefined } whereas you are passing as parameter the constant newBook. If I understand correctly, your image is being physically saved but the information on req.body are not being filled in and so you cannot save the information of the constant newBook in the database?

  • No, it’s the other way around... the data from req.body are saved in the bank and the req.file no. Only store physically in the folder uploads and does not record the file name in the data box in the fields theBook and cover.

  • if I understand correctly the behavior is this. The file is saved physically in the folder uploads. In your database you should create a reference to this file by saving its name, for example. The image bytes will not be saved in the database unless you change your code and adopt a new strategy. You would like to save the image directly in the database?

  • See if this post helps you if I don’t quite understand: https://stackoverflow.com/questions/56359137/how-may-i-upload-file-with-formdata-to-node-js-with-express

  • This is exactly what I would like, but however it does not save the file name in the database. Returns Undefined. You got an idea how to make it better?

3 answers

0

The problem is that you have an array of files, so it would be:

const filename = req.files[index].filename;
  • The index needs to be defined, otherwise your role will not be specific. we will continue having same problem Undefined or not defined.

0


After many weeks of research, I finally managed to solve the problem. The solution is simple req.files[nome-do-campo][0].filename... This way the implementation would look like this:

router.post('/add', accessControl, fileBook, async (req, res, next) => {
var erros = []

    if(!req.body.title || typeof req.body.title == undefined || req.body.title == null){
        erros.push({texto: "Título inválido"})
    }

    if(!req.body.author || typeof req.body.author == undefined || req.body.author == null){
        erros.push({texto: "Autor inválido"})
    }

    if(erros.length > 0){
        res.render("pages/ebooks/create", {erros: erros})
    }else{
        //const { filename } = req.file;
        const newBook = {
            title: req.body.title,
            preface: req.body.preface,
            author: req.body.author,
            genre: req.body.genre,
            publisher: req.body.publisher,
            edition: req.body.edition,
            isbn: req.body.isbn,
            pages: req.body.pages,
            cover: req.files['cover'][0].filename,
            theBook: req.files['theBook'][0].filename,
            type: req.body.type,
            tags: req.body.tags

        }
        new eBook(newBook).save().then(function(){
            req.flash("success_msg", "eBook adicionado com sucesso!");
            res.redirect("/ebook/biblioteca");
            console.log(newBook);
        }).catch(function(err){
            console.log(err);
            req.flash("error_msg", "Houve um erro ao salvar o eBook! Tente novamente");
            res.redirect("/ebook/biblioteca");
        });
    }});

0

Horacio, the example below is a code that I wrote a while ago and that works correctly. I removed some points that are not part of the understanding. Another point is that if working with Array the files must be accessed through the req.files instead of req.file:

exports.post = async (req, res) => {
    var multer = null;
    try {
        multer = require('multer');
    } catch (ex) {
        // TODO console.error(ex);
        // TODO return res.json();
    }

    var upload = null;
    try {
        var path = require('path');
        var storage = multer.diskStorage({
            destination: function (req, file, cb) {
                // process.env.DIRETORIOUPLOAD = diretório
                // onde o arquivo será salvo
                cb(null, process.env.DIRETORIOUPLOAD);
            },
            filename: function (req, file, cb) {
                fileExtension = file.originalname.split('.')[1];

                // Não faz parte da questão mas estou dando um novo nome para o arquivo
                // físico
                const novoNome = require('crypto').randomBytes(64).toString('hex');
                cb(null, novoNome + path.extname(file.originalname));
            }
        });

        upload = multer({ storage: storage }).fields([
            // O name do input deve ser "anexo"
            { name: 'anexo', maxCount: 1 }
        ]);
    } catch (ex) {
        // TODO console.error(ex);
        // TODO return res.json();
    }

    upload(req, res, async err => {
        if (err) {
            // TODO console.error(ex);
            // TODO return res.json();
        }

        var obj = {
            // Informações postadas além do anexo
            campo1: req.body.campo1,
            campo2: req.body.campo2,

            // Novo nome do arquivo atribuído mais acima
            nomeArquivo: req.files['anexo'][0].filename,
            extensao: req.files['anexo'][0].filename.split('.')[1],

            // Nome original do arquivo
            nomeOriginal: req.files['anexo'][0].originalname,
            mimetype: req.files['anexo'][0].mimetype
        };

        // TODO salvar o "obj" no DB
        // TODO res.json();
    });
}

More details about the documentation: https://github.com/expressjs/multer

Browser other questions tagged

You are not signed in. Login or sign up in order to post.