I'm trying to save uploaded file name into db? thanks.
Basically how can I pass multer file.name into database.
My attempt is using this var: var fileimage = file.name;
router.use(multer({ // https://github.com/expressjs/multer
dest: './uploads/',
limits : { fileSize:100000 },
rename: function (fieldname, filename) {
return filename.replace(/\W+/g, '-').toLowerCase();
},
onFileUploadData: function (file, data, req, res) {
// file : { fieldname, originalname, name, encoding, mimetype, path, extension, size, truncated, buffer }
var params = {
Bucket: 'lemybucket01',
Key: file.name,
Body: data
};
s3.putObject(params, function (perr, pres) {
if (perr) {
console.log("Error uploading data: ", perr);
} else {
console.log("Successfully uploaded data to myBucket/myKey");
}
});
},
onFileUploadComplete: function (file) {
var fileimage = file.name;
}
}));
router.route('/')
//POST a new prod
.post(function(req, res) {
if(req.files.fileimage !== undefined){ // `image` is the field name from your form
//res.redirect("/uploads"); // success
}else{
res.send("error, no file chosen");
}
// Get values from POST request. These can be done through forms or REST calls. These rely on the "name" attributes for forms
var username = req.body.username;
//call the create function for our database
mongoose.model('Prod').create({
username : username,
fileimage : fileimage
}, function (err, prod) {
if (err) {
res.send("There was a problem adding the information to the database.");
} else {
//Prod has been created
console.log('POST creating new prod: ' + prod);
res.format({
//HTML response will set the location and redirect back to the home page. You could also create a 'success' page if that's your thing
html: function(){
// If it worked, set the header so the address bar doesn't still say /adduser
res.location("prods");
// And forward to success page
res.redirect("/prods");
},
//JSON response will show the newly created prod
json: function(){
res.json(bloprodb);
}
});
}
})
});
The req.files.fileimage !== undefined is always false?
The variable fileimage you declared in the following has limited scope
onFileUploadComplete: function (file) {
var fileimage = file.name;
}
If you want to pass some data(like fileimage) from one middleware to another you can use something like this.
onFileUploadComplete: function (file, req, res) {
var fileimage = file.name;
req.middlewareStorage = {
fileimage : fileimage//,
//otherKey : otherValue
}
}
and you can save in the db as
var fileimage = req.middlewareStorage.fileimage;
mongoose.model('Prod').create({
username : username,
fileimage : fileimage
}, function (err, prod) {
// do some stuff
});
Related
I am new in Node js API and I'm trying to upload an Image using multer + express + mongoose + postman
CODE:
var storage = multer.diskStorage({
destination: function (request, file, callback) {
callback(null, 'public/images/course');
},
filename: function (request, file, callback) {
return callback(null, file.originalname)
}
});
var upload = multer({storage : storage})
router.post('/course', upload.single('thumbnail'),async(req, res) => {
try{
var course = new Course({
name : req.body.name,
thumbnail : "placeholder" // set to path where file is uploaded
})
await course.save()
res.status(201).send(course)
}catch(e){
res.status(400).send(e)
}
})
I use postman to post request using form data and it creates an image with its originalFilename but i want the filename to be id generated by mongoose and i have seen somewhere that i can use filesystem for that but is there any way i can upload file after id is generated because when i do like this
var storage = multer.diskStorage({
destination: function (request, file, callback) {
callback(null, 'public/images/course');
},
filename: function (request, file, callback) {
if (request.data) {
console.log(file)
// TODO: consider adding file type extension
fileExtension = file.originalname.split('.')[1]
return callback(null, `${request.path}-${request.data._id.toString()}.${fileExtension}`);
}
// fallback to the original name if you don't have a book attached to the request yet.
return callback(null, file.originalname)
}
});
var upload = multer({storage : storage}).single('thumbnail')
router.post('/course',(req, res) => {
console.log(req.body)
const course = new Course({
name : req.body.name,
thumbnail : req.body.name
})
//console.log(course)
req.data = course
//console.log(req.file)
upload(req, res, function (err) {
if (err instanceof multer.MulterError) {
// A Multer error occurred when uploading.
} else if (err) {
// An unknown error occurred when uploading.
}
// Everything went fine.
})
})
Then i got request body empty.
Thanks in advance
I'm working currently on the Google API. I try to upload a file to some folders on the cloud.
When I try to pass the values of req.body as callback arguments, my console returns me that req is NOT defined.
However, just before to call the function, I make a test to appreciate the values of my variables and the test return me some values.
Here my router.js :
router.post("/files", function(req, res){
console.log("request reached !");
console.log("req.body.word :" + req.body.word); // "some word"
console.log("req.body.url :" + req.body.url);// "some url"
// I catch theses value in some variable
var word = req.body.word;
var url = req.body.url;
DriveAPI.insertDrive(word, url); // Now my console return me that
// req is **Not** defined
});
Here my quickstart.js :
module.exports.insertDrive = function (word, url) { // again, req is Not defined
folderId = 'some id';
var fileMetadata = {
'name': req.body.word ,
parents: [folderId]
};
var media = {
mimeType: 'image/jpg',
body: fs.createReadStream(req.body.url)
};
drive.files.create({
resource: fileMetadata,
media: media,
fields: 'id'
}, function (err, file) {
if (err) {
// Handle error
console.error(err);
} else {
console.log('File Id: ', file.id);
}
console.log("insert Drive finished =) !")
});
}
How pass the value of my req.body as arguments of my callback?
Thanks
I am having a problem to redirect the page after a successful file upload using multer. With the file upload i am also saving some text into the database. Here's my code.
Question :
When the file and the contents are saved in the DB how can I redirect the page to a new URL ?
I am currently using res.redirect('product/item'); but nothing happens. I also tried using res.render, but the page did not redirect.
Multer method to upload a file to Amazon S3
var upload = multer({
storage: multerS3({
s3: s3,
bucket: 'nameofthebucket',
metadata: function (req, file, cb) {
var ext = file.originalname.split('.').pop();
cb(null, {fieldName: 'file.fieldname' + '.' + ext});
},
filename: function(req,file,cb){
var ext = file.originalname.split('.').pop();
cb(null, Date.now() + '.' + ext);
},
key: function (req, file, cb) {
var ext = file.originalname.split('.').pop();
cb(null, Date.now() + '.' + ext);
}
})
})
var upload = upload.array('fileup', 10);
The code responsible to upload the file and the content
router.post('/uploadfileandcontent',function(req,res,next){
upload(req,res,function(err) {
if(err) {
} else {
saveRecordsToDB(req, function(err,data){
if (err) {
res.redirect('/errorpage');
} else {
res. redirect('product/item');
}
});
}
});
});
Function that saves records to DB and makes the callback
function saveRecordsToDB (req, callback){
var args = {
data: {
"name" : req.body.name, //
"age" : req.body.age
},
headers: { "Content-Type": "application/json" }
};
// registering remote methods
client.registerMethod("postMethod", "http://url/uploadfileandcontent", "POST");
var req =client.methods.postMethod(args, function (data, response) {
callback(null, 'success?');
});
req.on('error', function (err) {
console.log('error');
});
}
Note: I also made use of NODE REST CLIENT to send http request.
This should work. Tell me if it doesn't.
router.post('/uploadfileandcontent', function(req,res,next){
upload(req,res,function(err) {
if(err) {
res.send('Error while uploading.');
}
saveRecordsToDB(req, function(err,data){
if (err) {
console.log(err);
req.flash('error', { msg: 'Error while saving data.' }); // Flash message -> need to configure your template to show it
}
// Saved to DB
req.flash('success', { msg: 'Saved' });
res.redirect('/product/item'); // go to this page
});
});
});
UPDATE
You will need to include const flash = require('express-flash'); to use flash message. Then you can load it to your app like this: app.use(flash());. The app is express loaded like this: const app = express();.
In your HTML you will access it in an array. Example using Jade:
//success
if messages.success
for success in messages.success
div #{success.msg} // Saved
//Error
if messages.errors
for error in messages.errors
div #{error.msg} // Error while saving data.
i want to upload the file into a folder which should be get from form data submit by user. which is req.body.coursename
/*conditions for directory check*/
var isvalidate = function (data) {
var data = data;
var dir = '../uploads'+'/'+data;
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
return dir;
} else {
return dir;
}
};
/*multer*/
var date = moment().format('YYYY-MM-DD');
var storage = multer.diskStorage ({
destination: function (req, file, callback) {
console.log("filename upload",file.originalname);
callback(null, isvalidate(req.body.coursename));
},
filename: function (req, file, callback) {
//console.log("filename upload",file.originalname);
callback(null, date+ '-' +file.originalname );
}
});
var data = multer({ storage : storage }).any();
/*file upload*/
router.post('/create',function(req, res) {
console.log(req.body);
data(req, res, function(err) {
console.log(req.body);
//isvalidate (req.body.coursename);
if (err) {
res.json({error_code:1,err_desc:err});
return;
}
});
});
How can I create a folder with the name req.body.coursename for file upload?
You can't but you can move the file to other locations after the file is uploaded. You could make your storage object a module and change the directory dynamically via init
var multer = require('multer'); // middleware for handling multipart/form-data,
// Constructor
module.exports = function (name) {
try {
// Configuring appropriate storage
var storage = multer.diskStorage({
// Absolute path
destination: function (req, file, callback) {
callback(null, './uploads/'+name);
},
// Match the field name in the request body
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + Date.now());
}
});
return storage;
} catch (ex) {
console.log("Error :\n"+ex);
}
}
OR Use busboy
var Busboy = require('busboy');
var fs = require('fs');
app.post('.....',fucntion(req, res, next){
var busboy = new Busboy({ headers: req.headers });
busboy.on('field', function(fieldname, val) {
req.body[fieldname] = val;
});
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
fstream = fs.createWriteStream("path/desiredImageName");
file.pipe(fstream);
fstream.on('close', function() {
file.resume();
});
})
return req.pipe(busboy);
})
OR you can use changedest
app.post('/api/:type', multer({
dest: './uploads/',
changeDest: function(dest, req, res) {
var newDestination = dest + req.params.type;
var stat = null;
try {
stat = fs.statSync(newDestination);
} catch (err) {
fs.mkdirSync(newDestination);
}
if (stat && !stat.isDirectory()) {
throw new Error('Directory cannot be created because an inode of a different type exists at "' + dest + '"');
}
return newDestination
}
}), function(req, res) {
//set your response
});
I would like to move a small image from one server to another (both running node). As I search, I haven't found enough. This post remains unanswered.
As I started experimenting I wrote the following to the first server :
app.post("/move_img", function(req, res) {
console.log("post handled");
fs.readFile(__dirname + "/img_to_move.jpg", function(err, data) {
if (err) throw err;
console.log(data);
needle.post(server2 + "/post_img", {
data: data,
name : "test.jpg"
}, function(result) {
console.log(result);
res.send("ok");
});
});
});
This part seems to be working as I could be writing the data in the same server (using fs.writeFile) recreate the img.
Now as I am trying to handle the post in the other server I have a problem.
Server2:
app.post('/post_img', [ multer({ dest: './uploads/images'}), function(req, res) {
console.log("body ",req.body) // form fields
console.log("files ",req.files) // form files
res.send("got it");
}]);
This way i get an empty object in the files and the following in the body: { 'headers[Content-Type]': 'application/x-www-form-urlencoded', 'headers[Content-Length]': '45009' }
I think I could use busboy as an alternative but I can't make it to work. Any advice, tutorial would be welcome.
I solved my problem by using the following code,
server1 (using needle) :
app.post("/move_img", function(req, res) {
console.log("post handled")
var data = {
image:{
file: __dirname + "/img_to_move.jpg",
content_type: "image/jpeg"}
}
needle.post(server2 + "/post_img", data, {
multipart: true
}, function(err,result) {
console.log("result", result.body);
});
})
Server 2:
app.use('/post_img',multer({
dest: '.uploads/images',
rename: function(fieldname, filename) {
return filename;
},
onFileUploadStart: function(file) {
console.log(file.originalname + ' is starting ...')
},
onFileUploadComplete: function(file) {
console.log(file.fieldname + ' uploaded to ' + file.path)
}
}));
app.post('/post_img', function(req, res) {
console.log(req.files);
res.send("File uploaded.");
});
An alternative for the server 1 is the following (using form-data module):
var form = new FormData();
form.append('name', 'imgTest.jpg');
form.append('my_file', fs.createReadStream(__dirname + "/img_to_move.jpg"));
form.submit(frontend + "/post_img", function(err, result) {
// res – response object (http.IncomingMessage) //
console.log(result);
});
I'd simply read your file from the first server with the function readFile() and then write it to the other server with the function writeFile().
Here you can see use of both functions in one of my servers.
'use strict';
const express = require('express');
const multer= require('multer');
const concat = require('concat-stream');
const request = require('request');
const router = express.Router();
function HttpRelay (opts) {}
HttpRelay.prototype._handleFile = function _handleFile (req, file, cb) {
file.stream.pipe(concat({ encoding: 'buffer' }, function (data) {
const r = request.post('/Endpoint you want to upload file', function (err, resp, body) {
if (err) return cb(err);
req.relayresponse=body;
cb(null, {});
});
const form = r.form();
form.append('uploaded_file', data, {
filename: file.originalname,
contentType: file.mimetype
});
}))
};
HttpRelay.prototype._removeFile = function _removeFile (req, file, cb) {
console.log('hello');
cb(null);
};
const relayUpload = multer({ storage: new HttpRelay() }).any();
router.post('/uploadMsgFile', function(req, res) {
relayUpload(req, res, function(err) {
res.send(req.relayresponse);
});
});
module.exports = router;
see multer does all the tricks for you.
you just have to make sure you use no middle-ware but multer to upload files in your node starting point.
Hope it does the tricks for you also.