undefined filename error with multer nodejs express - node.js

multer is causing uncaught error though if i do req.file i am able log image without any issue however when i do req.file.filename i am getting uncaught error, in the form name image is correctly declared and i can see image on terminal on post request through req.file once again. thanks
const router = express.Router();
const bodyParser = require("body-parser")
const multer = require("multer");
const path = require("path");
const fs = require("fs");
const upload = multer({ dest: "uploads/" });
app.use(bodyParser.urlencoded({ extended: false }));
router.post("/", upload.single("image"), async (req, res, next) => {
var fileName = req.file.filename;
console.log(fileName);
})

Related

POST req body return empty array

i have a problem when POST some data in POSTMAN my problem is during "post" method /auth/login req.body return empty array.
Postman return empty object only if i use POST method with use form-data, if i change to xxx-www-form-urlencoded whatever works fine. I wanna know why it works so
const express = require('express');
const mongoose = require('mongoose');
const app = express();
require('dotenv').config();
const port = process.env.PORT || 5000;
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use("/static", express.static(__dirname + "/assets"))
app.post('/auth/login', (req, res) => {
res.status(200).json(req.body)
})
mongoose.connect("mongodb://localhost:27017")
.then(() => {
app.listen(port, () => {
console.log('port' + port)
})
})
I'm assuming you mean application/x-www-form-urlencoded instead of xxx-www-form-urlencoded and you mean multipart/form-data instead of form-data.
These 2 content-types are completely different encodings. When you called:
app.use(express.urlencoded({ extended: true }));
You added a middleware that can parse application/x-www-form-urlencoded, but that does not mean it automatically parses other formats too. It's only for that format, just like express.json() is only for the application/json format.
I solved this, i just created multer in my controller and it work how i wanted
const express = require('express');
const router = express.Router();
const { getUsers, createNewUser } = require('../controllers/newUser')
const path = require('path');
const multer = require('multer');
const upload = multer();
router.get('/', getUsers)
router.get('/:id', (req, res) => res.send('get single user'))
router.post('/', upload.none(), createNewUser)
module.exports = router;

Express API is not getting called from react.js

Hi everyone facing issue for API not getting called from node(express.js).
When i call it using controller file it returns status 200 with data=[] empty array and does not print in console ' [] ' but when i call the same API in the product.js(API file) it gets called
gives response as status 200 and data=hi
i have disabled app.disable("etag"); in app.js
Calling Api from react.js to Express.js API
export const getRandomProductAPI = () => Axios.get(`${url}/v1/product/getRandomProduct`);
I am having API folder in which i am reciving the request from react.js in Product.js(API file).
const express = require("express");
const router = express.Router();
const multer = require("multer");
const productController = require("../controllers/ProductController");
const storage = multer.memoryStorage({
destination: function (req, file, callBack) {
callBack(null, "");
},
});
const uploadProduct = multer({ storage }).single("productImage");
const updateProduct = multer({ storage }).single("newEditImage");
// router.get("/getRandomProduct", (req, res) => {
// res.status(200).send("hi");
// });
router.post("/add", uploadProduct, productController.addProduct);
router.get("/:category", productController.getProduct);
router.delete("/:id/:imageName", productController.deleteProduct);
router.patch("/", updateProduct, productController.updateProduct);
router.get("/Id", productController.getLatestProductId);
router.get("/getRandomProduct", productController.getRandomProduct);
module.exports = router;
API which is got called is the last one-> router.get("/getRandomProduct",roductController.getRandomProduct);
Controller Code ProductController.js
const getRandomProduct = async (req, res) => {
console.log("called");
res.status(200).send("hi");
};
module.exports = {
addProduct,
getProduct,
deleteProduct,
updateProduct,
getLatestProductId,
getRandomProduct,
};
App.js code
const express = require("express");
const morgan = require("morgan");
const helmet = require("helmet");
const cors = require("cors");
const path = require("path");
require("dotenv").config();
const middlewares = require("./middlewares");
const api = require("./api");
const app = express();
if (process.env.NODE_ENV === "production") {
app.use(express.static(path.join(__dirname, "client/build")));
}
app.use(morgan("dev"));
app.use(helmet());
app.use(cors());
app.use(express.json());
// app.disable("etag");
app.get("/", (req, res) => {
res.json({
message: "🌎🌍🌏 Furnitures ",
});
});
app.use("/v1", api);
app.use(middlewares.notFound);
app.use(middlewares.errorHandler);
module.exports = app;

form-data in node not showing

I have a node express set up.
While using Postman, Iam able to see data sent through x-www-form-urlencoded but the same is not being shown through form-data.
below are the codes
Server.js
const express = require('express')
var cors = require('cors')
const app = express()
var bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
var cookieParser = require('cookie-parser')
app.use(cookieParser())
app.use(cors())
const index = require("./routes/index")
app.use("/", index)
const port = process.env.PORT || 3060;
app.listen(port, function listenHandler() { console.log(`Running on ${port}`) });
Index.js
const express = require('express')
const router = express.Router()
var pool = require('./mysqlConnector')
const asyncMiddleware = require('./asyncMiddleware')
const func = require('./functions')
const time = new Date().toISOString().slice(0, 19).replace('T', ' ')
const nodemailer = require("nodemailer");
router.use('/auth', require('./auth')
Auth .js
const express = require('express')
const router = express.Router();
var pool = require('./mysqlConnector')
const asyncMiddleware = require('./asyncMiddleware')
const jwt = require('jsonwebtoken')
const bcrypt = require('bcryptjs')
const nodemailer = require("nodemailer");
const func = require('./functions')
router.post('/register', asyncMiddleware( async(req, res, next) => {
res.send({ success: true, message: req.body })
}))
You should use Multer to handle form-data.
Multer is a node.js middleware for handling multipart/form-data
body-parser middleware can't handle multipart/form-data.
This does not handle multipart bodies, due to their complex and typically large nature.
In case you need to handle a text-only multipart form, you should use the .none() method:
E.g.
const express = require('express');
const bodyParser = require('body-parser');
const multer = require('multer');
const upload = multer();
const app = express();
app.use(upload.none());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.post('/auth/register', (req, res) => {
res.send({ success: true, message: req.body });
});
const port = process.env.PORT || 3060;
app.listen(port, function listenHandler() {
console.log(`Running on ${port}`);
});
postman:

multer - req.file is undefined.

I am creating an app using Node, Express and Handlebars and multer for uploading images. Every time I submit the form, req.file is undefined. I've spent the entire day troubleshooting but can't figure out what I'm doing wrong.
Router File:
const express = require('express');
const router = express.Router();
const multer = require('multer');
const mongoose = require('mongoose');
const path = require('path');
const methodOverride = require('method-override');
//Set Storage Engine
const storage = multer.diskStorage({
destination: './public/uploads/images',
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now() +
path.extname(file.originalname));
}
});
const upload = multer({
storage: storage
}).single('featuredImage');
//Change Featured Image - POST
router.post('/saveImage/:id', (req, res) => {
console.log(req.file);
//removed the rest of the code to keep it simple. req.file here is always undefined.
});
Form
<form action="/saveImage/{{pitch.id}}" method="POST" enctype="multipart/form-data">
<div class="form-group">
<label for="featuredImage">Featured Image</label>
<input type="file" name="featuredImage" id="featuredImage">
</div>
<input type="submit" value="SAVE">
</form>
app.js these requires are in the app.js file.
const express = require('express');
const exphbs = require('express-handlebars');
const path = require('path');
const passport = require('passport');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const flash = require('connect-flash');
const session = require('express-session');
const methodOverride = require('method-override');
const nodemailer = require('nodemailer');
//Set StaticFolder
app.use(express.static(path.join(__dirname, 'public')));
You need to add upload.single('featuredImage') as middleware for the respective route as follows.
const upload = multer({storage: storage});
//Change Featured Image - POST
router.post('/saveImage/:id',upload.single('featuredImage'), (req, res) => {
console.log(req.file);
//removed the rest of the code to keep it simple. req.file here is always undefined.
});
In my case it was issue with image size. I resolved it with defining multer limit as follows:
const upload = multer({ storage: storage, limits: { fieldSize: 10 * 1024 * 1024 } }); //10MB
Took me ages to figured out.
Maybe this can help someone
Please refer to this question. It has answer you are looking for.
node js multer file upload not working. req.file and req.files always undefined
You have to pass middleware
router.post('/saveImage/:id', upload.single('featuredImage'), (req, res) => {
console.log(req.file);
});
At first I was having the same issue! But when I added this :
const { storage } = require ('debug/src/browser');
... it worked.
This is my multer code :
const { storage } = require('debug/src/browser');
const multer = require('multer');
const MINE_TYPES = {
'image/jpg' : 'jpg',
'image/jpeg': 'jpeg',
'image/png':'png'
}
const Storage = multer.diskstorage({
destination: (req, file, callback)=>{
callback(null, "public/images/articles")
},
filename: (req, file, callback) => {
var name = Math.floor(Math.random() * Math.floor(15258652325)).tostring()
name = Math.floor(Math.random() * Math.floor(15258652325)).toString();
name = Math.floor (Math.random() * Math.floor(15258652325)).toString();
name = Math.floor(Math.random() * Math.floor(15258652325)).tostring();
name = Math.floor(Math.random() * Math.floor
(15258652325)).toString();
name += Date.now();
const extension = MINE_TYPES[file.mimetype];
name += extension;
callback(null,name);
module.exports = multer({ storage: Storage)).
single('image');
I was facing the same issue and you can solve it by following these steps:
1- First add these line in your server.js or index.js root file
app.use(express.json());
app.use(express.urlencoded({
extended: true,
})
);
2- Create a folder name middleware and inside it create a file name upload.js or any name that you want.
3- Place the following code in upload.js file
const multer = require("multer");
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "public/");
},
filename: function (req, file, cb) {
const imgName = file.originalname;
cb(null, imgName );
},
});
const upload = multer({
storage: storage,
});
module.exports = upload;
4- Now you can use this middleware in any route. For example:
const upload = require("../middlewares/fileUpload");
router.route("/send").post(upload.single("profile"),
((req,res) => {
*your controller logic here*
});
**Note: Here profile is the name of the file key that you are sending**
Use this:
var fileupload = require("express-fileupload");
app.use(fileupload());

Unable to use Multer middleware

I am working on nodejs application i which i have to implement the upload files to AWS S3. I am trying to implement the multer to parse the multipart/form-data following the article here
I am working on express 4
here is my server.ts code
var express = require('express');
var app = express();
var multer = require('multer');
app.use(multer({
dest: './client2/content/images/uploads',
}))
It giving me error
app.use() requires middleware functions
I want to access the uploaded files as req.files
please guide me how to get the files so that i can upload it to AWS S3
This books seems to be obsolete, it's better to use the doc on the npmjs page. For example:
var express = require('express');
var app = express();
var router = express.Router();
var multer = require('multer');
var upload = multer({ dest: __dirname + '/uploads' });
// single file upload
router.post('/upload', upload.single('test'), function (req, res, next) {
var file = req.file;
console.log(file);
});
// multiple files
router.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
// req.files is array of `photos` files
// req.body will contain the text fields, if there were any
})

Resources