Unable to use Multer middleware - node.js

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
})

Related

Why my Express Static Folder aren't Working Properly

why my static folder isn't working if I use Cloudinary and express-fileupload for profile IMG (client-side) upload and multer for post cover image upload only one of them are working if comment out the other one please help me to get rid of this problem...
const express = require("express");
const cors = require('cors');
const fileUpload = require('express-fileupload');
const app = express();
app.use(cors());
// Below code is for client side profile photo upload it is stores in cloudinary
app.use(fileUpload({
useTempFiles: true
}));
// Below code is static post cover photo it is stores in static folder in backend
app.use('/', express.static('uploads'));
app.get("/", (req, res, next) => {
res.send("Api running");
});
// Connecting Routes
app.use('/', require('./routes/indexpost'));
app.use('/user', require('./routes/userRouter'));
app.use('/api', require('./routes/upload'));

undefined filename error with multer nodejs express

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);
})

how to upload and read a file with express

I have question.I've looked at some questions here, but I can't get the answer.My question is, I want to upload and read a json file, I try with "multer" but couldn't.So I want to put the file I upload to the result variable. Can you help me? How can I achieve this?
HTML;
<!DOCTYPE html>
<html lang="en">
<head></head>
<body>
<form action="/import" enctype="multipart/form-data" method="post">
<input type="file" name="filename">
<input type="submit" value="Upload">
</form>
</body>
</html>
Server.js
const express = require('express');
const multer = require('multer');
const upload = multer({
dest: 'uploads/' // "uploads"
});
const app = express();
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
route.post("/import", upload.single("filename") (req, res, next) => {
var result = require(# I want to send the json file I uploaded here, and I need to see the contents of the json file as is #)
res.json(result)
res.redirect("/")
});
app.listen(3000);
The upload.single() parses the data stream and saves as a file based on the configuration. In your case, it will look for filename field in the incoming request and save the file in the uploads/ folder. The metadata of the file is available in req.file object. You can simply do console.log(req.file) to see the information.
To read the content of the file, you can use req.file.path field. Here is how:
const fs = require("fs");
const path = require("path");
/** In the controller */
const absolutePath = path.join(__dirname, req.file.path);
const jsonString = fs.readFileSync(absolutePath, "utf-8");
const jsonObject = JSON.parse(jsonString);
console.log(jsonObject);
Here is how the complete server.js would look like:
const express = require("express");
const multer = require("multer");
const fs = require("fs");
const path = require("path");
const upload = multer({
dest: "uploads/" // "uploads"
});
const app = express();
app.get("/", (req, res) => {
res.sendFile(__dirname + "/index.html");
});
const route = express.Router();
route.post("/import", upload.single("filename"), (req, res, next) => {
console.log(req.file);
const absolutePath = path.join(__dirname, req.file.path);
const jsonString = fs.readFileSync(absolutePath, "utf-8");
const jsonObject = JSON.parse(jsonString);
console.log(jsonObject);
res.redirect("/");
});
app.use(route);
app.listen(3000);
I have added some parts which were missing from your snippet ( like express.Router ). They might be different though.

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());

How to upload file into project folder and get its name using multer and Node.js

I need to save file into folder and want to get that file's name to save into database using Node.js.
api.js:
var multer = require('multer')
var storage =multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './../uploads');
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + Date.now());
}
});
exports.saveCardDetails=function(upload.single('image'),req,res){
var name=req.body.name;
var company=req.body.company;
var position=req.body.position;
var mobile=req.body.mobile;
var email=req.body.email;
var landline=req.body.landline;
var url=req.body.url;
var postcode=req.body.postcode;
var address=req.body.address;
var image=req.body.image;
var userid=req.body.userid;
var profiletext=req.body.profile;
var biography=req.body.biography;
var token_id=req.body.token_id;
console.log('request',req);
}
server.js:
var express=require('express');
var morgan = require('morgan');
var http=require('http');
var bodyParser= require('body-parser');
var methodOverride = require('method-override');
var mongo = require('mongojs');
var session = require('express-session');
var app=module.exports=express();
var server=http.Server(app);
var port=8989;
var admin=require('./route/route.js');
var api=require('./api/api.js');
app.use(express.static(__dirname + '/public')); // set the static files location /public/img will be /img for users
app.use(morgan('dev')); // log every request to the console
app.use(bodyParser.urlencoded({ extended: false })) // parse application/x-www-form-urlencoded
app.use(bodyParser.json()) // parse application/json
app.post('/api/users/save-card-details',api.saveCardDetails);
After this I am getting the following error:
POST /api/users/save-card-details 413 13.277 ms - 1120
Error: request entity too large
at readStream (/opt/lampp/htdocs/heroku/FGDP/node_modules/raw-body/index.js:196:17)
at getRawBody (/opt/lampp/htdocs/heroku/FGDP/node_modules/raw-body/index.js:106:12)
at read (/opt/lampp/htdocs/heroku/FGDP/node_modules/body-parser/lib/read.js:76:3)
at urlencodedParser (/opt/lampp/htdocs/heroku/FGDP/node_modules/body-parser/lib/types/urlencoded.js:115:5)
at Layer.handle [as handle_request] (/opt/lampp/htdocs/heroku/FGDP/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/opt/lampp/htdocs/heroku/FGDP/node_modules/express/lib/router/index.js:312:13)
at /opt/lampp/htdocs/heroku/FGDP/node_modules/express/lib/router/index.js:280:7
at Function.process_params (/opt/lampp/htdocs/heroku/FGDP/node_modules/express/lib/router/index.js:330:12)
at next (/opt/lampp/htdocs/heroku/FGDP/node_modules/express/lib/router/index.js:271:10)
at logger (/opt/lampp/htdocs/heroku/FGDP/node_modules/morgan/index.js:144:5)
Here I am getting the image and need to save into folder. After saving into folder I need saved file name into exports.saveCardDetails function. My folder structure is given below.
--> api/api.js
--> upload
I am using multer npm package for this.
Looks like multer is failing for large file size.
Try setting the fieldSize variable in multer config like this -
multer({
storage: storage,
limits: { fileSize: maxSize }
})
You can find these settings here - https://www.npmjs.com/package/multer (search for limit).
Hope this helps!

Resources