Here is my code where I am getting the upload video and checking it extension when extention is not mp4 i want to return else statement and pass the the error from server but when i am getting this error and when i am console.log this error this print the server not responding 505 error it is working fine with when extention is mp4.
const videoStorage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, config.videoStorage);
},
filename: function (req, videoFile, cb) {
if (path.extension(videoFile.originalname) !== '.mp4') {
const name = `${videoFile
.fieldname}-${Date
.now()}_${
videoFile.originalname}`;
return cb(null, name.replace(/\s/g, ""));
} else {
return cb(new Error("sorry"));
}
}
});
MediaService
.uploadVideo(formData, this.getUploadProgress)
.then(data => {
let order = {
...this.state.project
};
if (!order.project) {
order = {
project: {
mediaId: data
}
};
}
order.project.mediaId = data;
console.log("videoid added ===", order);
this.setState({uploading: false, videoId: data, isValid: true, project: order});
message.success("Video uploaded successfully");
})
.catch(error => {
message.error(error);
this.setState({message: error, uploading: false});
});
};
Instead of throwing error,you can pass flag like this:
return cb({success:false,message:"false"});
This you can access in success promise of uploader.
Because when you are saying new Error(), i think it will throw an error on server side and it will not be able to send response to client.that is why you are not getting response on client side.
Related
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 have successfully used Multer with NestJs to check for fileTypes so only images are saved. However when a non image is uploaded the fileCheck works great but Nest returns a 500 error to the client. I want it to return an error message to the client.
Other answers on SO show how to do this using Node but I want to know how to do it using Nest. I followed a video tutorial to get this far but now need this extra functionality.
Controller.ts
#Controller("photos")
export class PhotosController {
#Post("upload")
#UseInterceptors(FileInterceptor("photo", {
storage: diskStorage({
destination: './uploads',
filename: editFileName
}),
fileFilter: imageFileFilter
}))
async uploadSingle(#UploadedFile() file) {
console.log(file);
const response = {
originalname: file.originalname,
filename: file.filename,
};
return response;
}
file-upload.utils.ts
export const imageFileFilter = (req, file, callback) => {
if (!file.originalname.match(/\.(jpg|jpeg|png|gif)$/)) {
return callback(new Error('Only image files are allowed!'), false);
}
callback(null, true);
};
export const editFileName = (req, file, callback) => {
const name = file.originalname.split('.')[0];
const fileExtName = extname(file.originalname);
const randomName = Array(4)
.fill(null)
.map(() => Math.round(Math.random() * 16).toString(16))
.join('');
callback(null, `${name}-${randomName}${fileExtName}`);
};
How can I catch the error in ImageFileFilter if it exists then still return a response to the client?
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
My goal is the following:
I want to get user uploaded PDF, extract the Text from within that PDF, assign the text to an array object. Once this is done I want to upload that file to an S3 bucket. Right now I am able to to do the first part without much issue. The reason why I am doing the local upload in the first place is so I can do the text extraction from PDF. These methods work on their own. If i want to upload to S3 it will and the database gets populated with the link for me to show it on the front-end but the BulletinMetaText field does not get populated with the extract text.
What way should I go about doing this?
If I have not been clear please let me know what more I can provide..
Multer methods:
let uploadToS3 = multer({
storage: multerS3({
s3: s3,
acl: "private",
bucket: env == "production" ? "xxxx" : "xxxx",
// metadata: function(req, file, cb) {
// console.log(file);
// console.log(req.body);
// cb(null, Object.assign({}, req.body));
// },
key: function(req, file, cb) {
// console.log(file);
cb(null, `${new Date().getFullYear()}/${file.originalname}`);
}
})
}).array("files");
// }).any();
var tempStorage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, "client/v1.7/src/assets/pdf/");
},
// By default, multer removes file extensions so let's add them back
filename: function(req, file, cb) {
cb(null, `${file.originalname}`);
}
});
var uploadToLocal = multer({ storage: tempStorage }).array("files");
let delay = time => {
return new Promise((resolve, reject) => {
setTimeout(function() {
resolve("DONE");
}, time);
});
};
Node/express Backend
if (req.params.type === "files") {
uploadToLocal(req, res, function(err) {
if (err) {
next({
status: 500, //Server Error
statusMessage: "Error: Failed to save file ",
catchError: err //System error
});
} else {
//TODO
let {
bulletinID,
bulletinUUID,
bulletinActive,
bulletinType,
bulletinCode,
bulletinGroup,
bulletinEn,
bulletinFr,
bulletinTitleEn,
bulletinDescriptionEn,
bulletinTitleFr,
bulletinDescriptionFr,
metaStringTags,
bulletinPermission
} = req.body.model;
uploadToS3(req, res, function(err) {
console.log("upload2Req");
console.log(req.body);
let bulletinFileEn,
bulletinFileFr = "";
// console.log("req.files");
console.log(req.files);
req.files.forEach(file => {
if (file.originalname && file.originalname.includes("_en")) {
console.log("file");
console.log(file);
console.log(file.key);
bulletinFileEn = file.key;
}
if (file.originalname && file.originalname.includes("_fr")) {
bulletinFileFr = file.key;
}
});
console.log(bulletinFileEn);
console.log(bulletinFileFr);
extract(
"client/v1.7/src/assets/pdf/test.pdf",
// req.files.originalname,
{ splitPages: false },
function(err, text) {
if (err) {
console.log(err);
return;
}
console.log("text");
// console.log(text);
bulletinMetaText = text;
if (err) {
next({
status: 500, //Server Error
statusMessage: "Error: Failed to save file locally ",
catchError: err //System error
});
} else {
// !~
let newBulletin = {
bulletinID: bulletinID ? bulletinID : "NULL",
bulletinUUID: bulletinUUID ? bulletinUUID : uuid(),
bulletinActive: bulletinActive ? bulletinActive : true,
postedByUserID: req.user.id,
postedByUserUUID: req.user.userUUID,
bulletinType: bulletinType,
bulletinCode: bulletinCode,
bulletinGroup: bulletinGroup,
bulletinEn: bulletinEn ? true : false,
bulletinFr: bulletinFr ? true : false,
//English Bulletin - File/Link
bulletinTitleEn: bulletinTitleEn,
bulletinDescriptionEn: bulletinDescriptionEn,
bulletinLinkEn: null,
bulletinFileEn: bulletinFileEn,
//French Bulletin - File/Link
bulletinTitleFr: bulletinTitleFr,
bulletinDescriptionFr: bulletinDescriptionFr,
bulletinLinkFr: null,
bulletinFileFr: bulletinFileFr,
metaStringTags: metaStringTags,
bulletinPermission: bulletinPermission,
bulletinTextScrape: bulletinMetaText
};
console.log(newBulletin);
InsertOrUpdateBulletin(newBulletin, req.user)
.then(result => {
res.status(200).json({
data: result,
status: 200, //Created
statusMessage: "Success: Bulletin Created"
});
})
.catch(error => {
next({
status: 500, //Server Error
statusMessage: "Error: Failed to save Bulletin ",
catchError: error //System error
});
});
}
}
);
});
}
});
}
This might help (keyword: might) but it uses express-fileupload. Still allows for server side manipulation of the data.
https://link.medium.com/U1SdsoHMy2
I'm a newbie trying to learn Nodejs. I've been trying to resolve an issue using an NPM module called Multer. I can't seem to write the right code to delete a User's image file or overwrite if the user uploads another one. Sorry for the inconvenience. Please help
My Delete Route works perfectly deleting both the "Posts" and "Image". However, my edit Route gives the below error
{"Error":{"errno":-4058,"syscall":"unlink","code":"ENOENT","path":"C:\cms\public\uploads\image-1568050604308.png"}}
const publicUploads = path.join(__dirname, '../../../public/uploads/');
const storage =
multer.diskStorage({
destination: publicUploads,
filename(req, file, cb){
cb(null,`${file.fieldname}-${Date.now()}${path.extname(file.originalname)}`)
}
});
const upload = multer({
storage,
limits: {
fileSize: 1000000
},
fileFilter(req, file, cb){
if(!file.originalname.match(/\.(jpeg|jpg|png)$/)){
return cb(new Error('Please upload an image file'))
}
cb(null, true)
}
})
router.put('/admin/posts/edit/:id', upload.single('image'), async (req, res) => {
const updates = Object.keys(req.body);
const allowedUpdates = ['title', 'body', 'status', 'image', 'allowComments'];
const isValid = updates.every(update => allowedUpdates.includes(update));
if(!isValid){
return res.send({Error: 'Invalid Update'})
}
try {
const post = await Post.findOne({_id: req.params.id});
if(!post){
return res.send({Error: 'Could not find your post'})
}
if(req.file){
fs.unlinkSync(`${publicUploads}${post.image}`);
post.image = req.file.filename
}
updates.forEach(update => {
post[update] = req.body[update]
})
post.allowComments = req.body.allowComments === 'on'? true:false;
await post.save();
req.flash('notice', 'Your post was edited successfully!')
res.status(200).redirect('/admin/posts')
} catch (error) {
res.send({Error: error})
}
}, (error, req, res, next) => {
res.send({Error: error})
})
You can delete the image natively with the Node package "fs". You don't need to use Multer for this:
// Remove old photo
if (oldPhoto) {
const oldPath = path.join(__dirname, "..", "images", oldPhoto);
if (fs.existsSync(oldPath)) {
fs.unlink(oldPath, (err) => {
if (err) {
console.error(err);
return;
}
res.status(200).send(userObj);
});
}
}