Cannot read properties of undefined (reading 'filename') nodejs --multer - node.js

I'm currently trying to make the user can edit their profile picture, I'm using nodejs, react & multer for that. On the other hand I receive an error when I send my form, I show you my code I hope you can help me.
Sending the form gives me no error when I put a req.body.file in my edit function but then the image of my profile is undefined,
I also tried req.file[0].filename, which doesn't work either.
I would like that when the user uploads an image it is downloaded in my images folder and that it is also displayed on the user's profile
I thank you in advance

when doing a put request you are sending your data in JSON not in form data. you need to do something like this
const onSubmit = () => {
const formData = new FormData();
formData.append("firstName", firstName);
....
formData.append("avatar", avatar);
also FileReader.readAsDataURL return string but multer needs value of type File, so we need to directly store event.target.files[0] inside state so that multer can read it.
make sure you have express middleware
app.use(express.json());
not but the least upload.single("avatar") it should be the name of variable
hope these changes help you.

I didn't see your implementation for React updateUser, but looks like you are using the key avatar when uploading a file but accessing it via image key.
Also just use file Blob from HTMLInput
const handleImgUpload = (e) => setAvatar(e.target.files[0])
Try to change your router to
router.put('/update/:id', requiresAuth, upload.single('avatar'), updateUser)
and make sure you submit the form with Content-Type header multipart/form-data

Related

Why node app crashes when req.files is null?

I have a frontend app(react) where the user can edit the product like price, description, delete images and add images.
The problem occurs when the user does not want to add new images.
Then on the backend(nodejs) req.files.newImages as I named it is null
and the backend crashes.
When I add one image or more everything works as it should because req.files.newImages has a value.
How to cover the case when the user does not want to add new images and prevent the app from crashing
I use express-fileupload and I use axios and put method to send data.
routes.put("/edit-product", (req, res) => {
console.log(req.files.newImages) // - result app crashed
}
Error in console: TypeError: Cannot read property 'newImages' of null;
You can simply check if there are any files like this:
if (req.files) {
// do something
}
Alternatively you can use optional chaining:
console.log(req.files?.newImages); // will log "undefined"
first check if it comes with console.log(req.files) with another name, if not, make sure you send it as "multipart" on the front-end side

Upload a pdf from a url into Firestore storage bucket (Node JS)

I am making a get request (using axios) to a pdf hosted at a url endpoint, which is returning an encoded stream as show below:
'%PDF-1.4\n%����\n1 0 obj\n<</Creator (Chromium)\n/Producer (Skia/PDF m78)\n/CreationDate (D:20211115122641+00\'00\')\n/ModDate (D:20211115122641+00\'00\')>>\nendobj\n3 0 obj\n<</ca 1\n/BM /Normal>>\nendobj\n4 0 obj\n<</Type /XObject\n/Subtype /Image\n/Width 1245\n/Height 249\n/ColorSpace /DeviceRGB\n/BitsPerComponent 8\n/Filter /DCTDecode\n/ColorTransform 0\n/Length 35434>> stream\n����\u0000\u0010JFIF\u0000\u0001\u0001\u0000\u0000\u0001\u0000\u0001\u0000\u0000��\u0002(ICC_PROFILE\u0000\u0001\u0001\u0000\u0000\u0002\u0018\u0000\u0000\u0000\u0000\u0002\u0010\u0000\u0000mntrRGB XYZ
I am then uploading this to our storage bucket using the following:
const file = bucket.file(path);
const fileOptions = {contentType: 'application/pdf'};
return file.save(data, fileOptions)
.then(() => {
return {
url: file.getSignedUrl({action: 'read', expires: expiryDate}),
path
}
});
However the URL returned, when opened just displays a blank PDF (containing the correct number of pages) but without any content.
What is the best way for downloading and uploading a PDF from a url into storage? Would it be this approach (though i am not sure what i am missing), or is there a way to upload the URL I have to storage directly?
The code that you are using sets the content type as ‘application/pdf’. However, it is unclear how you are downloading the object from the storage that could have caused this behaviour.
const file = bucket.file(path);
const fileOptions = {contentType: 'application/pdf'};
return file.save(data, fileOptions)
In general,File.createWriteStream() method is used to upload arbitrary data to a file. The details about this can be referred to from the documentation.
Also, you could use Multer to upload files from a function. Multer is a node.js middleware for handling multipart/form-data, which is primarily used for uploading files. Multer adds a body object and a file or files object to the request object. The body object contains the values of the text fields of the form, the file or files object contains the files uploaded via the form. You can also refer to the documentation for more information on Multer.

Node.js Export and use post request in another command line script

i have a problem which i think it's a basic yet couldn't figure it out. I have a post request in a js file and i export it to app.js. And i have another js file which will be executed as command line script only. What i want is; using the same post internally by sending the body. I want to call the post and get the response in this file. Here is my code;
Customers.js;
router.post('/', async (req, res) => {
//some work
res.status(201).send(v_return);
});
module.exports.router = router;
Command-line.js;
const customer = require('./routes/customers')
//..some irrelevant code
//this is what i've tryed, i need to send cust[0] as req body
var res = customer.router.use(function(req,res){
req.body=cust[0];
});
console.log(res); //i need the response
//..some irrelevant code
Basically i need to make the post with v_cust[0] as body. And get the response. Thanks in advance.
EDIT: I've create seperate function that takes body and do the work. Then i used it both post and command-line script. So i have a solution but still i don't know if i can make post request in the api. If there is an answer for it, i would appreciate it.

node js resize png doesnt work on aws lambda only

var newImage = await sharp(originalBuffer).resize(newWidth, newHeight, {
fit: sharp.fit.inside,
withoutEnlargement: true
});
console.log(`after resize before to buffer ${typeof newImage} `, newImage)
// works on localhost mac but not on aws lambda
// https://github.com/lovell/sharp/issues/2085#issuecomment-587187740
newImage = await newImage.toBuffer();
the error is
Error: undefined Input buffer contains unsupported image format Error: Input buffer contains unsupported image format
using express-fileupload for files uploading. don't think it's relevant here. also tried multer
I've researched a lot and haven't found a solution
Im not sure but if the lambda function linked with api gateway, before the run the sharp you need to see with console log when sending data to function. Is it coming undefiend or same as your data ? Sometimes we cant get the Api gateway request body from function. Try to send with application/json header or form data.

Is it ok to work directly on the data in req.body?

I'm working on an app in Node/Express/Jade.
I have a GET route which render a form. When the user submit this, a POST route is handling the request. I use bodyParser, which populate the req.body.
I then sanitize, validate and generate new data directly in the req.body:
// Shorthand variable
var doc = req.body;
// Sanitise and transform user input
doc.company = sanitize( doc.company ).trim();
doc.contact_person = sanitize( doc.contact_person ).trim();
...
// Validate user input
validator.check( doc.company, 'Some error message' ).notEmpty();
validator.check( doc.contact_person, 'Another error message' ).notEmpty();
...
// Generate new object data
doc.slug = sanitize( doc.company ).toSlug();
...
Question: is if there are any special reason for me not to edit the data directly in the req.body? Should I instead making a new "doc" object from the data in req.body, and in that new object sanitize, validate and add the new generated data.
It's fine to edit data in req.body. The only thing you should be aware of is that the next route or middleware will get a modified version of req.body.
So, you may create a single route/middleware to sanitize and transform your req.body and then use transformed results in multiple routes.
You can definitely modify it. For example, the express.json middleware parses raw body data into JSON for the rest of the middleware chain.
It's best to use a copy if your intention isn't to alter data for the rest of the chain, even if it won't interfere with correct operation. It prevents sometimes hard-to-debug errors that might crop up in later development.

Resources