I sent a request from the client with an image link in the body, in the node server I use jimp (Jimp NPM) to resize the image which I was sent, then I need to save the image to mongodb with multer but I have some confuse with this step, does anyone have any idea ? thanks !
here is my code so far :
const multer = require('multer');
const GridFsStorage = require('multer-gridfs-storage');
const mongoose = require('mongoose');
exports.resizeImage = async function (req, res) {
let storageFS = new GridFsStorage({
db: app.get("mongodb"),
file: (req, file) => {
return new Promise((resolve, reject) => {
crypto.randomBytes(16, (err, buf) => {
if (err) {
return reject(err);
}
const filename = file.originalname;
const fileInfo = {
filename: filename,
bucketName: 'images'
};
resolve(fileInfo);
});
});
}
});
var upload = multer({ storage: storageFS }).single('image');
try {
Jimp.read(req.body.imagePath)
.then(image => {
image.resize(150, 150, function (err, img) {
// How to store img to mongodb with multer here ?
});
})
.catch(err => {
throw err
});
} catch (error) {
res.send(error);
}
}
Related
I want to get the image that have been posted to the nodejs flutter. I am using the bellow code in the flutter:
_openCameraPicture(BuildContext context) async {
var image = await ImagePicker().pickImage(source: ImageSource.camera);
setState(() async {
selectedImage = File(image!.path);
if (Network.isConnected) {
var request = http.MultipartRequest(
'POST', Uri.parse("${Network.serverUrl}/upload_image"));
request.fields['title'] = "testImage";
request.files.add(http.MultipartFile.fromBytes(
'picture', selectedImage!.readAsBytesSync(),
filename: selectedImage!.path.split("/").last));
var response =
await request.send().then((value) => {Navigator.pop(context)});
// if (response.statusCode == 200) {
// Do something ...
// }
}
});
}
In my nodejs server api I use:
router.post("/upload_image", PhoneInfoCtrl.apiUploadImage);
But I can not get the image and upload it to the server. My apiUploadImage is like:
static async apiUploadImage(req, res, next) {
try {
console.log(req);
res.sendStatus(200);
} catch (error) {
//res.status(500);
}
}
How may I extract the image from req? I tested some ways but was not possible. Is something wrong with my flutter code?
Solved by using multer in my router in nodejs.
const path = require('path');
const multer = require("multer");
const storage = multer.diskStorage({
destination : (req, file, cb) =>{
cb(null , "./public/images")
},
filename: (req, file, cb) =>{
console.log(file);
cb(null , Date.now() + path.extname(file.originalname));
},
});
then:
router.post("/upload_image", upload.single("picture"),myController.apiUploadImage);
I am trying to upload an image from my front end to the backend but it it doesn't send the image in the request
It says that the formdata is empty and it says that there's no image found, where is the problem and how can I fix this error?
Here is the code from the Frontend made in react:
const [userInfo, setuserInfo] = useState({
file:[],
filepreview:null,
});
const handleInputChange = (event) => {
setuserInfo({
...userInfo,
file:event.target.files[0],
filepreview:URL.createObjectURL(event.target.files[0]),
});
}
const [isSucces, setSuccess] = useState(null);
const submit = async () =>{
const formdata = new FormData();
formdata.append('avatar', userInfo.file);
console.log(formdata)
Axios.post("http://localhost:4000/imageupload", formdata,{
headers: { "Content-Type": "multipart/form-data" }
})
.then(res => { // then print response status
console.warn(res);
if(res.data.success === 1){
setSuccess("Image upload successfully");
}
})
}
The code of the Backend made in NodeJS:
const storage = multer.diskStorage({
destination: path.join(__dirname, './temp', 'uploads'),
filename: function (req, file, cb) {
// null as first argument means no error
cb(null, Date.now() + '-' + file.originalname )
}
})
app.post('/imageupload', async (req, res) => {
try {
// 'avatar' is the name of our file input field in the HTML form
let upload = multer({ storage: storage}).single('avatar');
upload(req, res, function(err) {
// req.file contains information of uploaded file
// req.body contains information of text fields
if (!req.file) {
return res.send('Please select an image to upload');
}
else if (err instanceof multer.MulterError) {
return res.send(err);
}
else if (err) {
return res.send(err);
}
const classifiedsadd = {
image: req.file.filename
};
res.send("ok")
});
}catch (err) {console.log(err)}
})
Edit:
Multer is essentially a nodejs router,i.e. a function that can be pipelined between your HTTP request and HTTP response.
I think that you should first make multer analyze your HTTP content and to actually populate the req.file before actually evaluate express parsers do their job.
const storage = multer.diskStorage({
destination: path.join(__dirname, './temp', 'uploads'),
filename: function (req, file, cb) {
// null as first argument means no error
cb(null, Date.now() + '-' + file.originalname )
}
})
let upload = multer({ storage: storage});
app.post('/imageupload', upload.single('avatar'), async (req, res) => {
try {
// 'avatar' is the name of our file input field in the HTML form
// req.file contains information of uploaded file
// req.body contains information of text fields
if (!req.file) {
return res.send('Please select an image to upload');
}
else if (err instanceof multer.MulterError) {
return res.send(err);
}
else if (err) {
return res.send(err);
}
const classifiedsadd = {
image: req.file.filename
};
res.send("ok")
}catch (err) {console.log(err)}
})
I am assuming that your upload code is working. Have you tried to read the HTTP request from your browser to see that the image has been correctly attached to the request?
Because probably the issue lies in the fact that you are not actually parsing the image.
const file = new File(userInfo.file, "avatar.png", {
type: 'image/png' // choose the appropriate
});
const formdata = new FormData();
formdata.append('avatar', file);
console.log(formdata)
I want to upload the excel file on the MySQL database and then import it back,
I have uses the technologies :
express
multer
mysql2
read-excel-file
sequelize
But when I upload the excel, req.file is showing undefined. in the excel controller folder.
I have checked the multer twice but it seems to be right.
I don't know what is the problem ...
Your answer will help me.
Thanks
Server-side code:
const multer = require("multer");
const excelFilter = (req, file, cb) => {
if (
file.mimetype.includes("excel") ||
file.mimetype.includes("spreadsheetml")
) {
cb(null, true);
} else {
cb("Please upload only excel file.", false);
}
console.log("done");
};
var storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, __basedir + "/uploads");
},
filename: (req, file, cb) => {
console.log(file.originalname);
cb(null, `${Date.now()}-bestfile-${file.originalname}`);
},
});
var uploadFile = multer({ storage: storage, fileFilter: excelFilter });
module.exports = uploadFile;
Excel controller
const db = require("../../models");
const Branch = db.bestdata;
const readXlsxFile = require("read-excel-file/node");
const upload = async (req, res) => {
try {
console.log(req);
if (req.file == undefined) {
return res.status(400).send({ msg: "No, Excel File Uploaded" });
}
let path = __basedir + "/uploads/" + req.file.filename;
readXlsxFile(path).then((rows) => {
// skip header
rows.shift();
let branchArray = [];
rows.forEach((row) => {
let branchtoArray = {
id: row[0],
branch_name: row[1],
mgr_id: row[2],
mgr_start_date: row[3],
};
branchArray.push(branchtoArray);
});
Branch.bulkCreate(branchArray)
.then(() => {
res.status(200).send({
message: "Uploaded the file successfully: " + req.file.originalname,
});
})
.catch((error) => {
res.status(500).send({
message: "Fail to import data into database!",
error: error.message,
});
});
});
} catch (error) {
console.log(error);
res.status(500).send({
message: "Could not upload the file: " + req.file.originalname,
});
}
};
const GetImport = (req, res) => {
Branch.findAll()
.then((data) => {
res.send(data);
})
.catch((err) => {
res.status(500).send({
message:
err.message || "Some error occurred while retrieving tutorials.",
});
});
};
module.exports = {
upload,
GetImport,
};
Router:
const express = require("express");
const router = express.Router();
const excelController = require("../controller/BestData/excel.controller.js");
const uploadFile = require("../middlewares/upload.js");
let routes = (app) => {
router.post("/upload", uploadFile.single("file"), excelController.upload);
router.get("/import", excelController.GetImport);
app.use("/excel", router);
};
module.exports = routes;
Snapshot of postman test
enter image description here
Excel File uploading
enter image description here
The answer is simple: Destination and path should be the same.:
I'm trying to do the following in Node.js using express router, Multer-S3, Multer, AWS and Mongodb.
I want to:
1: Check if filetype is image, price is number etc (some kind of quality check)
2: If above true, upload image to S3 to get Image url
3: If Image Url was generated, upload to Mongodb, including the generated image url..
Trying with below code but can only get one of these to work at same time..
const express = require("express");
const router = express.Router();
const shopController = require("../controllers/shop");
router.post(
"/shop/create/:shopId",
shopController.creatingShop,
shopController.createShopItem
);
const ShopItem = require("../models/shopitem"); //Mongoose Schema
const multer = require("multer");
const fileview = multer().single("file1"); //Trying to use this to view file before uploading to S3
const uploader = require("../services/file-upload");
const singleUpload = uploader.single("file1"); //Using this to upload to S3
exports.createShopItem = (req, res, next) => {
fileview(req, res, function (err) {
const file = req.file;
const title = req.body.title;
const price = req.body.price;
const description = req.body.description;
const location = req.body.location;
const user = "OrreSnorre";
if (
file.mimetype != "image/jpeg" &&
file.mimetype != "image/jpg" &&
file.mimetype != "image/png"
) {
return next(new Error("invalid file type"));
}
if (file.size > 2500000) {
return next(new Error("Your image is to big. Maximum 2.5mb"));
}
next();
console.log(
"Here I want to add upload text to mongoDb... including URL from S3 after it is generated"
);
});
exports.creatingShop = (req, res, next) => {
singleUpload(req, res, function (err) {
console.log(req.file);
// res.json({ "image-url": req.file.location });
});
next();
};
Anyone got ideas? Or examples that work?
Best regards,
Oscar
There are 2 ways to do this, either you can use only multer or multer-s3.
For simplicity, I will show you the way using only multer.
Flow of processing as follow:
Multer process and save to local
You read from local, and upload to s3 using s3 SDK (You should explore how to remove the file after upload as well, but I wont clutter you with this logic here)
If upload is successful, you retrieve the URL and pass it to your MongoDB.
// Make "temp" directory as multer.diskStorage wont create folder
fs.mkdir('./temp', { recursive: true }, (err) => {
if (err) throw err;
});
const PORT = parseInt(process.argv[2]) || parseInt(process.env.PORT) || 3000;
// Multer
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './temp');
},
filename: function (req, file, cb) {
let extArray = file.mimetype.split('/');
let extension = extArray[extArray.length - 1];
cb(null, new Date().getTime() + '.' + extension);
},
});
const upload = multer({ storage: storage });
const endpoint = new AWS.Endpoint(AWS_S3_HOSTNAME);
const s3 = new AWS.S3({
endpoint,
accessKeyId: AWS_S3_ACCESSKEY_ID,
secretAccessKey: AWS_S3_SECRET_ACCESSKEY,
});
// Get the uploaded file in local here
const readFile = (path) =>
new Promise((resolve, reject) =>
fs.readFile(path, (err, buff) => {
if (null != err) reject(err);
else resolve(buff);
})
// Upload to AWS S3 here
const putObject = (file, buff, s3) =>
new Promise((resolve, reject) => {
const params = {
Bucket: AWS_S3_BUCKET_NAME,
Key: file.filename,
Body: buff,
ACL: 'public-read',
ContentType: file.mimetype,
ContentLength: file.size,
};
s3.putObject(params, (err, result) => {
if (null != err) reject(err);
else resolve(file.filename);
});
});
);
const mongoClient = new MongoClient(MONGO_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
app.post('/api/post', upload.single('imageFile'), async (req, res) => {
readFile(req.file.path)
.then((buff) =>
// Insert Image to S3 upon succesful read
putObject(req.file, buff, s3)
)
.then((results) => {
// build url of the resource upon successful insertion
const resourceURL = `https://${AWS_S3_BUCKET_NAME}.${AWS_S3_HOSTNAME}/${results}`;
const doc = {
comments,
title,
ts: new Date(),
image: resourceURL, // Your URL reference to image here
};
// Insert to your mongoDB
mongoClient
.db(MONGO_DB)
.collection(MONGO_COLLECTION)
.insertOne(doc)
.then((results) => {
// delete the temp file when no error from MONGO & AWS S3
fs.unlink(req.file.path, () => {});
// return the inserted object
res.status(200).json(results.ops[0]);
})
.catch((error) => {
console.error('Mongo insert error: ', error);
res.status(500);
res.json({ error });
});
})
.catch((error) => {
console.error('insert error: ', error);
res.status(500);
res.json({ error });
});
}
I am creating a React and Node application, and at the moment I need to upload a PDF file, the code works well, but I was wondering how to use front variables to create the file name by multer.
The code...
Front:
const handleSubmit = async (e) => {
const dado = new FormData()
const year = data.split("/")
const dd = year[0];
const mm = year[1];
const aaaa = year[2];
dado.append('file', file)
dado.append('uni', uni)
dado.append('dd', dd)
dado.append('mm', mm)
dado.append('aaaa', aaaa)
console.log(dado)
axios.post("http://localhost:8080/api/comprebem/file", dado, {
})
.then(res => {
console.log(res.statusText)
})
}
Back:
const storage = multer.diskStorage({
destination:"../login/public/comprebem/ibama/",
filename: function (req, file, cb) {
console.log(file);
cb(null, `unidade${"req['uni']"}_data${file.originalname}` )
}
})
const upload = multer({ storage: storage }).single('file')
app.post('/api/comprebem/file',function(req, res) {
upload(req, res, function (err) {
if (err instanceof multer.MulterError) {
return res.status(500).json(err)
} else if (err) {
return res.status(500).json(err)
}
return res.status(200).send(req.file)
})
});