Express - multer fileFilter error handling - node.js

I'm tryng to upload a file and the upload goes ok! The problem is when I try to upload some file that is not accepted according to me fileFitler handling. I would like to receive some error in console or redirect the user to the back page, but I'm just receiving a error on brower : cannot read read property filename of undefined.
But, if I upload some extension that is accepted, goes ok!
Here is my code:
const mongoose = require('mongoose');
const multer = require('multer');
const uuidV4 = require('uuid/v4');
const Video = require('../models/videoModel');
function fileFilter(req, file, cb){
const extension = file.mimetype.split('/')[0];
if(extension !== 'video'){
return cb(null, false), new Error('Something went wrong');
}
cb(null, true);
};
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads')
},
filename: function (req, file, cb) {
const newName = uuidV4();
const extension = file.mimetype.split('/')[1];
cb(null, newName +`.${extension}`);
}
});
var upload = multer({ storage: storage, fileFilter: fileFilter});
exports.uploadVideo = upload.single('file'); // the single param should be the name of the file input form
exports.CreateVideo = (req, res) => {
const newVideo = {title: req.body.title, path: req.file.filename};
Video.create(newVideo, function(err, result){
if(err){
console.log('Não foi possível realizar o upload do vídeo.' + err);
}
else{
console.log('Vídeo upado com sucesso!');
res.redirect('/');
console.log(result);
}
})
};
exports.Home = (req, res) =>{
res.render('index');
};
exports.ShowVideos = (req, res) =>{
Video.find({}, function(err, result){
if(err){
res.redirect('/');
}
else{
res.render('video', {videoData:result});
}
})
};

The get an error on the console, you could change your fileFilter and pass an error to the cb function. See:
function fileFilter(req, file, cb){
const extension = file.mimetype.split('/')[0];
if(extension !== 'video'){
return cb(new Error('Something went wrong'), false);
}
cb(null, true);
};
Hope it helps!!

Related

upload images with nodejs

i have a user.js in model folder
const UserSchema = new mongoose.Schema({
name: {
type: String,
},
profile_pic: {
data: Buffer,
contentType: String
}
})
i want to upload a profile picture
and in the router folder i defined the storage using multer
const storage = multer.diskStorage({
destination: (req, file, callback) => {
callback(null, './images')
},
filename: (req, file, callback) => {
callback(null , Date.now()+ file.originalname)
}
})
const upload = multer({
storage : storage,
limits : {
fieldSize : 1024*1024*3
}
})
router.post('/image' , upload.single('image'),image)
using postman i tried to upload an image .. it uploaded successfully and stored in the defined folder (images)
but i want to store the image in the model too
how to store it in the controller folder user.js
Try the example below
const app = require("express")();
const multer = require('multer')
const firstLocation = multer.diskStorage({
destination: function (req, file, cb) {');
cb(null, './imagesFolder/')
},
filename: (req, file, callback) => {
callback(null , Date.now()+ file.originalname)
}
});
const secondLocation = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './modelFolder/')
},
filename: (req, file, callback) => {
callback(null , Date.now()+ file.originalname)
}
});
const firstPath = multer({ storage: firstLocation })
const secondPath = multer({ storage: secondLocation })
function fileUpload(req, res, next) {
firstPath.single('file')(req, res, next);
secondPath.single('file')(req, res, next);
next();
}
app.post("/", fileUpload, (req, res) => {
res.send("Received file");
});
app.listen(3000, () => {
console.log("Server started");
});
If you run the above code and send a request to localhost:3000 then you will notice that two directories created named imagesFolder and modelFolder. Inside those folders, you will see the file that you have uploaded.
Updated answer in response to comments for Mongo schema,
const imagePath = '/path/to/myImage.jpg';
const imageUp = mongoose.model('imageUp', UserSchema);
mongoose.connection.on('open', function () {
imageUp.remove((err) => {
if (err) throw err;
const up = new imageUp;
up.img.data = fs.readFileSync(imagePath); // read from you folder
up.img.contentType = 'image/jpg'; // set the content tpe to image format
up.save((err, a) => { // save or upload image
if (err) throw err; // throws error if anything goes wrong
app.get('/', (req, res, next) => {
imageUp.findById(up, (err, doc) => { // fetch image from db by id and send in response as required.
if (err) return next(err);
res.contentType(doc.img.contentType);
res.send(doc.img.data);
});
});
}
Ref:- https://www.geeksforgeeks.org/upload-and-retrieve-image-on-mongodb-using-mongoose/

How to upload multi part data from forms to google drive using multer and google drive apis in node.js?

Currently the image gets stored in my upload folder. Since i am new to node.js and multer can anyone guide me on how to store these images to google drive?
https://developers.google.com/drive/api/v3/quickstart/nodejs
When through these link but dont know how to implement it in my project. The code provided in this link uploades an image to google drive but the path of the file has to be harcoded. Can anyone please help me out. I am beginner in back end development.
here is my code for reference
```
const express = require("express");
const router = express.Router();
const multer = require("multer");
const path = require("path");
//set storage engine
const storage = multer.diskStorage({
destination: "./public/uploads/",
filename: function(req, file, cb) {
cb(null,file.fieldname + "-" + Date.now() + path.extname(file.originalname));
}
});
//init upload
const upload = multer({
storage: storage,
limits: { fileSize: 10000000 },
fileFilter: function(req, file, cb) {
checkFileType(file, cb);
}
}).single("myImage");
//check file type
function checkFileType(file, cb) {
//Allowed ext
const fileTypes = /jpeg|jpg|png|gif/;
//check ext
const extname = fileTypes.test(
path.extname(file.originalname).toLocaleLowerCase()
);
//check mime
const mimetype = fileTypes.test(file.mimetype);
if (mimetype && extname) {
return cb(null, true);
} else {
cb("Error: Images Only!");
}
}
router.get("/", (req, res) => res.render("./index"));
router.post("/upload", (req, res) => {
upload(req, res, err => {
if (err) {
res.render("index", {
msg: err
});
} else {
// console.log(req.file);
// res.send("test");
if (req.file == undefined) {
res.render("index", {
msg: "Error: No File Selected!"
});
} else {
res.render("index", {
msg: "File uploaded!",
file: `uploads/${req.file.filename}`
});
}
}
});
});
module.exports = router;
```

Multer fileFilter is not getting called and req.body is empty

for some reason the fileFilter on multer is not getting called.
here is my Controller (i am using express routers)
const express = require('express');
const router = express.Router();
const UploadController = require('../controllers/UploadController');
router.route('/upload').post(UploadController.upload);
module.exports = router;
and this is the controller
const multer = require('multer');
const fs = require('fs');
module.exports = {
upload: function (req, res) {
let storage = multer.diskStorage({
destination: function (req, file, cb) {
console.log('here');
const filesDir = './uploads/' + req.body.ref;
if (!fs.existsSync(filesDir)) {
fs.mkdirSync(filesDir);
}
cb(null, filesDir);
},
filename: function (req, file, cb) {
let extArray = file.mimetype.split("/");
let extension = extArray[extArray.length - 1];
cb(null, req.body.type + '-' + Date.now() + '.' + extension);
},
fileFilter : function (req, file, cb) {
if (!file.originalname.match(/\.(jpg|jpeg|png|gif)$/)) {
return cb(new Error('Only image files are allowed!'), false);
}
cb(null, true);
}
})
const upload = multer({ storage: storage }).single('file');
upload(req, res, function (err) {
if (err instanceof multer.MulterError) {
res.send({
error: err
});
} else if (err) {
res.send({
error: err
});
}else{
res.send({
file: req.file,
body: req.body
});
}
});
}
}
I have following issues:
The fileFilter function is not even called so its not validating files
the req.body on the upload function (upload: function (req, res)) is empty it is only available in diskStorage and last upload function (upload(req, res, function (err)) so i cannot validate the body data also.
I had the same problem. the fileFilter function has to be defined inside multer, not inside the diskStorage function.
To make it a bit more readable I defined the storage and filter in variables instead of making everything inside the multer call.
// storage settings
const multerStorage = multer.diskStorage({
destination: function(req, file, next) {
next(null, './public/files');
},
filename: function(req, file, next) {
const sanitizedName = file.originalname
.replace('/[^a-z0-9\./gi', '-')
.replace('/-{2,}/g', '-')
.toLowerCase();
const name = Date.now() + '-' + sanitizedName;
// sending the file name to be stored in the database
req.body.filename = name;
next(null, name);
},
limits: {
fileSize: 25000000
}
});
// filter function
const multerFilter = function(req, file, cb) {
const ext = path.extname(file.originalname).toLowerCase();
if (ext !== '.pdf') {
cb(new Error('File must be in PDF format.'));
}
cb(null, true);
}
And then applying the storage settings and filter function to multer:
const upload = multer({
storage: multerStorage,
fileFilter: multerFilter
});

Multer callback when file is uploaded in the disk completely

I have written the code for multer as shown below:
const storage = multer.diskStorage({
destination(req, file, callback) {
callback(null, './public/images')
},
filename(req, file, callback) {
profile_image = `${file.fieldname}-${Date.now()}${path.extname(file.originalname)}`;
callback(null, profile_image)
}
});
const xyz = (req, res) => {
upload = multer({
limits: {
fileSize: 1000000,
files: 2
},
storage,
fileFilter(req, file, callback) {
const ext = path.extname(file.originalname);
if (ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
return callback(res.end('Only images are allowed'), null)
}
callback(null, true);
}
}).any();
upload(req, res, err => {
})
upload starts working the moment there is no error in uploading file, but not when the file is uploaded successfully in the disk. So is there any other callback through which I can know when the file is successfully uploaded in the disk?
Try this it might solves your issue. You can check success in upload function in below example.
var Express = require('express');
var multer = require('multer');
var bodyParser = require('body-parser');
var app = Express();
app.use(bodyParser.json());
var Storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, "./Images");
},
filename: function (req, file, callback) {
callback(null, file.fieldname + "_" + Date.now() + "_" + file.originalname);
}
});
var upload = multer({ storage: Storage }).array("imgUploader", 3); //Field name and max count
app.get("/", function (req, res) {
res.sendFile(__dirname + "/index.html");
});
app.post("/api/Upload", function (req, res) {
upload(req, res, function (err) {
if (err) {
return res.end("Something went wrong!");
}
return res.end("File uploaded sucessfully!.");
});
});
app.listen(2000, function (a) {
console.log("Listening to port 2000");
});
Check in your upload function like this
upload(req, res, err => {
if (err) {
res.end("Something went wrong!");
}
res.end("File uploaded sucessfully!.");
}

nodejs how to upload image from API

I am new to node JS and i have made function for uploading image from API.
But when i hit the URL from postman using form-data having field name image then in response it shows me.
Here is the postman image
Error uploading file
below is my code
My router.js contain:-
var express = require('express');
var router = express.Router();
var ctrlSteuern = require('../controllers/steuern.controllers.js');
router
.route('/steuern/image_upload')
.post(ctrlSteuern.imageUpload);
in Controller i have:-
var multer = require('multer');
var multiparty = require('multiparty');
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './image');
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + Date.now());
}
});
var upload = multer({ storage : storage}).single('image');
module.exports.imageUpload = function(req, res){
upload(req,res,function(err) {
if(err) {
return res.end("Error uploading file.");
}
return res.end("File is uploaded");
});
}
Here is my code for saving image to folder.
exports.saveMedia = (req, res) => {
const storage = multer.diskStorage({
destination: (req, file, callback) => {
callback(null, (config.const.path.base + config.const.path.productReviewMedia));
},
filename: (req, file, callback) => {
callback(null, Date.now() + '-' + file.originalname);
}
});
const upload = multer({storage: storage}).any('file');
upload(req, res, (err) => {
if (err) {
return res.status(400).send({
message: helper.getErrorMessage(err)
});
}
let results = req.files.map((file) => {
return {
mediaName: file.filename,
origMediaName: file.originalname,
mediaSource: 'http://' + req.headers.host + config.const.path.productReviewMedia + file.filename
}
});
res.status(200).json(results);
});
}
Here is post man request.

Resources