This question has been asked before. But as I have failed to get solution for my problem, I am asking again.
I am trying to upload image for a property using multer package as form-data so I can store other data and path of image in the database. I am using node express.
My api--
api.post('/service', upload.single('servicesImage'),
(req, res, next) => {
console.log(req.file);
Company.find({ domain: req.headers.domain },
(err, company) => {
const servicecontent = new Servicecontent({
description: req.body.description,
created_at: Date.now(),
created_by: req.body.user_id,
company_domain: req.headers.domain,
company_uuid: company[0].uuid,
image: req.file.path,
})
servicecontent.save(err => {
console.log(err);
});
res.json({ status: "success" });
});
});
I watched a tutorial, and from that I added these codes to upload image and other options--
const storage = multer.diskStorage({
destination: function(req, file, cb){
cb(null, './src/uploads/');
},
filename: function(req, file, cb){
cb(null, new Date().toISOString()+ file.originalname);
},
});
const upload = multer({storage: storage, limits:{
fileSize: 1024*1024*5
},
fileFilter: fileFilter
});
const fileFilter = (req, file, cb) =>{
if(file.mimetype=== 'image/jpeg' || file.mimetype=== 'image/png'){
cb(null,true);
}else{
cb(null,false);
}
};
Now when I send data and image through Postman , from console.log(req.file)
I get valid data as I saw from the tutorial. Api responds without any errror, and in database I can see all datas are stored including image path. But the issue I am facing is that in src/upload folder is empty, no image is uploaded.
N.B. -- I am using linux 18.04 Os, and fs package can't be installed. So src/upload folder wasn't creating when I were sending req, so I created this directory from folder.
Edit: I can upload image with this code now, I don't exactly know why this wasn't working earlier. I should close this question, if possible.
I can upload image with this code now, I don't exactly know why this wasn't working earlier. I should close this question, if possible.
Try this to store images.
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/')
},
filename: function (req, file, cb) {
console.log(file);
cb(null, makeid(3) + file.originalname)
}
})
var upload = multer({ storage: storage })
`
Related
I am using node and express for backend and Mongo DB for storage.I am using multer middleware for storing image,i got a problem and the problem is when i store an image from local host it get saved in my backend and also shown in database,but when i deploy the same api on heroku or any other app the image is shown in database but it is not stored in my backend.I have tested the code on postman,what may be the issue?
Following below is my code on node js:
router.use(express.static(__dirname + 'public'));
let storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'public')
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
}
})
let upload = multer({ storage: storage })
router.post('/fellows-details', upload.single('image'), async (req, res) => {
const { error } = FellowsDetails(req.body);
if (error) return res.status(400).send({ message: error.details[0].message });
const fellow = new fellowdetails({
name: req.body.name,
details: req.body.details,
image: req.file.filename
})
try {
fellow.save()
res.status(200).send({ message: 'fellows detail saved successfully' })
} catch (err) {
res.status(400).send(err);
}
})
It will become easy to store files after converting in string
you just have to convert string in image in your frontend
convert image in to base64 string using this code in your api and also don't forgot to delete file from upload folder
"img": new Buffer.from(fs.readFileSync(req.file.path)).toString("base64")
to delete the file
let resultHandler = function (err) {
if (err) {
console.log("unlink failed", err);
} else {
console.log("file deleted");
}
}
fs.unlink(req.file.path, resultHandler);
at your routes import multer
`multer const multer = require('multer');
const upload = multer({ dest: __dirname + '/uploads/images' });`
Add upload.single('img') in your request
router.post('/fellows-details', authorize([Role.ADMIN, Role.USER]),
upload.single('img'), usersController.fellowsdetails);
The filesystem on Heroku is not suitable for the persistent storage of data. The Heroku filesystem is ephemeral - that means that any changes to the filesystem whilst the dyno is running only last until that dyno is shut down or restarted. Each dyno boots with a clean copy of the filesystem from the most recent deploy
You can't store files on Heroku. Heroku automatically removed your uploaded files. You have to use external services like Amazon S3 or Azure Blob Storage.
https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/s3-node-examples.html
https://learn.microsoft.com/en-us/javascript/api/#azure/storage-blob/blockblobclient?view=azure-node-latest
If you don't want to set up an account with AWS to create an S3 bucket we also have add-ons here that handle storage and processing of static assets https://elements.heroku.com/addons
var dateString = Date.now();
var storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, './uploads/')
},
filename: (req, file, cb) => {
cb(null, dateString+'_'+file.originalname)
}
});
var maxSize=3 1000 1000;
var upload = multer({ storage: storage,
limits: { fileSize: maxSize }})
var upload = multer({ storage: storage , limits: { fileSize: maxSize }});
app.post("/fileupload", upload.single("fileToUpload"), function (req, res) {
console.log(req.file.originalname)
var uploaded = "http://localhost:4001/"+dateString+'_'+req.file.originalname;
console.log(uploaded)
res.json({status: 200,msg:'File saved successfully',data:uploaded});
});
Multer is not uploading files on server directory below my source code to upload file. file object is created that means when i log req.files file are present but not uploading to directory.im using POSTMAN for API Testing sending file through formdata->uploadfiles and with key "uploadfiles" destinition function is not called because log inside function is not console the name "Hello "
const storage = multer.diskStorage({
destination: function (req, file, cb) {
console.log("Hello Umesh");
cb(null, '../resources/uploads'); // Absolute path. Folder must exist, will not be created for you.
},
filename: function (req, file, cb) {
console.log("Hello Umesh");
cb(null, file.fieldname + '-' + Date.now());
}
});
const upload = multer({
storage: storage,
limit:{filesize:10}
}).single('uploadfiles');
router.post('/save', function (req, res) {
upload(req, res, function (err) {
if (err) {
res.json({
success: false,
message:err
});
}
else{
res.json({
success: true,
message: req.file
});
}
})
});
Try to use the absolute path to the storage location:
cb(null, require('path').join(__dirname, '..', 'resources', 'uploads'));
instead:
cb(null, '../resources/uploads');
Update:
Since the working directory for functions from the fs module is the project's root folder (if you run the project with the npm start command), you can simply use this:
cb(null, 'resources/uploads');
I have uploaded files of different types(image, pptx, video and docx) using Multer in the folder named 'uploads'.
var storage = multer.diskStorage({ //multers disk storage settings
destination: function (req, file, cb) {
cb(null, './uploads/');
},
filename: function (req, file, cb) {
var datetimestamp = Date.now();
cb(null, file.originalname);
}
});
var upload = multer({ //multer settings
storage: storage
}).single('file');
/** API path that will upload the files */
app.post('/upload', function(req, res) {
upload(req,res,function(err){
if(err){
res.json({error_code:1,err_desc:err});
return;
}
res.json({error_code:0,err_desc:null});
});
});
Now the uploaded files are being stored in 'uploads' folder like /uploads/demo.pptx
I need to fetch these and send the filepath or url of the stored files and send as a response to client so they can access to watch or download it.
Usually, files stored in DB when you need to do more than just serve them and upload new files. For this proposes, you could save only file's metadata to DB(such as size, type, path, name). However if you for some reason still need to store files in DB, MongoDB have GridFS component and provides a documentation about working with this component.
you can do something like this:-
var mongojs = require('mongojs');
var db = mongojs(//credential here);
var uploaded_file=db.collection("uploaded_file");
var storage = multer.diskStorage({ //multers disk storage settings
destination: function (req, file, cb) {
cb(null, './uploads/');
},
filename: function (req, file, cb) {
var datetimestamp = Date.now();
cb(null, file.originalname);
}
});
var upload = multer({ //multer settings
storage: storage
}).single('file');
/** API path that will upload the files */
app.post('/upload', function(req, res) {
upload(req,res,function(err){
if(err){
res.json({error_code:1,err_desc:err});
return;
}else{
uploaded_file.insert(res.file,function(err, saved) {// i am asuming res.file have the information you needed to send
if(err){
console.log("Unexpected error occurred during insertion in database:"+err);
}else{
res.send({error_code:0,file_info:res.file});
res.end();
}
});
}
});
});
I am using the following to upload files to a directory via Multer. It works great, but I need to perform some actions after upload that require the name of the file I just posted to the "upload" directory. How do I get the name of the file I just posted?
// Multer storage options
var storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, 'upload/');
},
filename: function(req, file, cb) {
cb(null, file.originalname + '-' + Date.now() + '.pdf');
}
});
var upload = multer({ storage: storage });
app.post('/multer', upload.single('file'), function(req, res) {
// Need full filename created here
});
var express=require("express");
var app=express();
var multer=require("multer");
var upload=multer({dest:"uploads/"});
app.post("/multer", upload.single("file"), function(req,res){
console.log(req.file.filename);
});
request.file gives the following stats, from which you would just need to pick request.file.originalname or request.file.filename to get the new filename created by nodejs app.
{
fieldname: 'songUpload',
originalname: '04. Stairway To Heaven - Led Zeppelin.mp3',
encoding: '7bit',
mimetype: 'audio/mp3',
destination: './uploads',
filename: 'songUpload-1476677312011',
path: 'uploads/songUpload-1476677312011',
size: 14058414
}
Eg, in nodejs express mvc app with ecma-6,
var Express = require('express');
var app = Express();
var multipartUpload = Multer({storage: Multer.diskStorage({
destination: function (req, file, callback) { callback(null, './uploads');},
filename: function (req, file, callback) { callback(null, file.fieldname + '-' + Date.now());}})
}).single('songUpload');
app.post('/artists', multipartUpload, (req, resp) => {
val originalFileName = req.file.originalname
console.log(originalFileName)
}
Accessing uploaded files data differs in Multer, depending whether you are uploading single or multiple files. Access data like so:
uploading single file:
req.file
uploading multiple files:
req.files
I found the answer on github, you have access to it in
res.req.file.filename
See there for more informations https://github.com/expressjs/multer/issues/302
app.post('/multer', upload.single('file'), function(req, res) {
// Need full filename created here
const file = req.file
if (!file) {
const error = new Error('Please upload a file')
error.httpStatusCode = 400
return next(error)
}
res.send(file) #Here
});
You need recover file from this line
res.send(file)
using file.filename
This output sample
{
"fieldname": "myFile",
"originalname": "isc te esta esperando.jpg",
"encoding": "7bit",
"mimetype": "image/jpeg",
"destination": "uploads",
"filename": "myFile-1602293858948.eaf",
"path": "uploads/myFile-1602293858948.eaf",
"size": 297720
}
using
request.file.filename
fieldname Field name specified in the form
originalname Name of the file on the user's computer
encoding Encoding type of the file
mimetype Mime type of the file
size Size of the file in bytes
I'm using "multer": "^1.0.6", And i Want to save image in upload folder.
My code is
app.post('/post', multer({dest: './uploads/'}).single('file'), function (req, res) {
response = {
message: 'File uploaded successfully',
filename: req.file.filename
};
res.end(JSON.stringify(response));
});
But I Have the file with this name in upload folder 8e6e425f8756e0bafb40ed1a3cb86964
Why I have this name without mimetype?
Multer saves files without extensions you can read this on GitHub:
filename is used to determine what the file should be named inside the folder. If no filename is given, each file will be given a random name that doesn't include any file extension.
If you want to save with the extension that you write your code like here:
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '/tmp/my-uploads')
},
filename: function (req, file, cb) {
cb(null, file.originalname); // modified here or user file.mimetype
}
})
var upload = multer({ storage: storage })
All information you can find here https://github.com/expressjs/multer/blob/master/README.md
Multer not worried about the extension of the file and leave it completely on your side: you have to define itself a function that will do it. For example, like this:
var multer = require('multer');
var upload = multer({ storage: multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads');
},
filename: function (req, file, cb) {
var ext = require('path').extname(file.originalname);
ext = ext.length>1 ? ext : "." + require('mime').extension(file.mimetype);
require('crypto').pseudoRandomBytes(16, function (err, raw) {
cb(null, (err ? undefined : raw.toString('hex') ) + ext);
});
}
})});
app.post('/post', upload.single('file'), function (req, res) {
response = {
message: 'File uploaded successfully',
filename: req.file.filename
};
res.end(JSON.stringify(response));
});