Getting MulterError: Unexpected field when adding mutiple file in put request - node.js

I am working on uploading multiple files for my product. But when i am trying to make a put request with those files, i got an error from multer on runtime
MulterError: Unexpected field
at wrappedFileFilter (G:\GIT\Mern_Eshop\back-end\node_modules\multer\index.js:40:19)
at Busboy.<anonymous> (G:\GIT\Mern_Eshop\back-end\node_modules\multer\lib\make-middleware.js:114:7)
at Busboy.emit (events.js:315:20)
at Busboy.emit (G:\GIT\Mern_Eshop\back-end\node_modules\busboy\lib\main.js:38:33)
at PartStream.<anonymous> (G:\GIT\Mern_Eshop\back-end\node_modules\busboy\lib\types\multipart.js:213:13)
at PartStream.emit (events.js:315:20)
at HeaderParser.<anonymous> (G:\GIT\Mern_Eshop\back-end\node_modules\dicer\lib\Dicer.js:51:16)
at HeaderParser.emit (events.js:315:20)
at HeaderParser._finish (G:\GIT\Mern_Eshop\back-end\node_modules\dicer\lib\HeaderParser.js:68:8)
at SBMH.<anonymous> (G:\GIT\Mern_Eshop\back-end\node_modules\dicer\lib\HeaderParser.js:40:12)
at SBMH.emit (events.js:315:20)
at SBMH._sbmh_feed (G:\GIT\Mern_Eshop\back-end\node_modules\streamsearch\lib\sbmh.js:159:14)
at SBMH.push (G:\GIT\Mern_Eshop\back-end\node_modules\streamsearch\lib\sbmh.js:56:14)
at HeaderParser.push (G:\GIT\Mern_Eshop\back-end\node_modules\dicer\lib\HeaderParser.js:46:19)
at Dicer._oninfo (G:\GIT\Mern_Eshop\back-end\node_modules\dicer\lib\Dicer.js:197:25)
at SBMH.<anonymous> (G:\GIT\Mern_Eshop\back-end\node_modules\dicer\lib\Dicer.js:127:10)
My code is here
router.put(
'/gallery-images/:id',
uploadOptions.array('images', 10),
async (req, res)=> {
if(!mongoose.isValidObjectId(req.params.id)) {
return res.status(400).send('Invalid Product Id')
}
const files = req.files;
let imagesPaths = [];
const basePath = `${req.protocol}://${req.get('host')}/public/uploads/`;
if(files) {
files.map(file =>{
imagesPaths.push(`${basePath}${file.filename}`);
})
}
const product = await Product.findByIdAndUpdate(
req.params.id,
{
images: imagesPaths
},
{ new: true}
)
if(!product)
return res.status(500).send('the gallery cannot be updated!')
res.send(product);
}
)
Any advice appreciated on where to look ?

This error generally occur when you are sending the name different on Images and using different multer configuration.
uploadOptions.array('images', 10) // check your are sending files with name 'images'
If the name is different, you should put that name instead.

Related

TypeScript and TSOA : Error Code LIMIT_UNEXPECTED_FILE with multiple #UploadedFile

I build a Rest API using typescript and TSOA with Express.
In a route, I try to receive multiple formfields (using the decorator #FormField) and multiple file fields (using the e decorator #UploadedFile).
see official link : https://tsoa-community.github.io/docs/file-upload.html
When I define only one file, the route is working well, but when I add a second file field, Multer complains with the error :
MulterError: Unexpected field
at wrappedFileFilter (*******\node_modules\multer\index.js:40:19)
at Busboy.<anonymous> (*******\node_modules\multer\lib\make-middleware.js:115:
7)
at Busboy.emit (node:events:526:28)
at Busboy.emit (node:domain:475:12)
at Busboy.emit (*******node_modules\busboy\lib\main.js:38:33)
at PartStream.<anonymous> (*******\node_modules\busboy\lib\types\multipart.js:
213:13)
at PartStream.emit (node:events:526:28)
at PartStream.emit (node:domain:475:12)
at HeaderParser.<anonymous> (*******\node_modules\dicer\lib\Dicer.js:51:16)
at HeaderParser.emit (node:events:526:28) {
code: 'LIMIT_UNEXPECTED_FILE',
field: 'banner',
storageErrors: []
}
this is the code of the controller:
#Post('')
public async create(
#Request() request: any,
#FormField() label: string,
#FormField() email: string,
#UploadedFile('logo') logo?: Express.Multer.File,
#UploadedFile('banner') banner?: Express.Multer.File,
): Promise<ResponseType> {
try {
const ns = await this.service.create({
label,
email,
},
request.user,
);
return { data: ns, success: true, detail: 'success' };
} catch (e: any) {
console.error(e);
this.setStatus(400);
return { detail: 'Validation Failed for Request Data : ' + e.message, success: false };
}
}
I think it is probably an error of Multer expecting only one file in the Request. So how can I specify that there is two files in the request with different fields using TSOA ?
did not receive an answer even though i posted an issue in github, sadly time to move away from TSOA.

trying to upload image to nodejs api but it returns with error

I am trying to upload image to my node.js server and when I upload nothing and just send the request to post without image, it works fine but whenever I try to post the image node.js shows error in console
here is the link to post
"http://localhost:3001/databaseGym/logo"
here is my code to handle post operation to that link
Router.post('/logo', upload.single('file'), (req, res) => {
console.log("working");
//res.json({ file: req.file });
res.send("done");
});
and here is my code for upload in upload.single()
// Create storage engine
const storage = new GridFsStorage({
url: url,
file: (req, file) => {
return new Promise((resolve, reject) => {
crypto.randomBytes(16, (err, buf) => {
if (err) {
return reject(err);
}
const filename = buf.toString('hex') + path.extname(file.originalname);
const fileInfo = {
filename: filename,
bucketName: 'logo'
};
resolve(fileInfo);
});
});
}
});
const upload = multer({ storage });
and here is the screenshot of postman app through which I am sending image
and here is the error
MulterError: Unexpected field
at wrappedFileFilter (D:\web dev\gym website\server_gym\node_modules\multer\index.js:40:19)
at Busboy.<anonymous> (D:\web dev\gym website\server_gym\node_modules\multer\lib\make-middleware.js:114:7)
at Busboy.emit (node:events:394:28)
at Busboy.emit (D:\web dev\gym website\server_gym\node_modules\busboy\lib\main.js:38:33)
at PartStream.<anonymous> (D:\web dev\gym website\server_gym\node_modules\busboy\lib\types\multipart.js:213:13)
at PartStream.emit (node:events:394:28)
at HeaderParser.<anonymous> (D:\web dev\gym website\server_gym\node_modules\dicer\lib\Dicer.js:51:16)
at HeaderParser.emit (node:events:394:28)
at HeaderParser._finish (D:\web dev\gym website\server_gym\node_modules\dicer\lib\HeaderParser.js:68:8)
at SBMH.<anonymous> (D:\web dev\gym website\server_gym\node_modules\dicer\lib\HeaderParser.js:40:12)
You should change the parameter in Postman from image to file as you specify the property name in the POST endpoint:
// you specify the `file` as the fieldname
Router.post('/logo', upload.single('file'), (req, res) => {
console.log("working");
//res.json({ file: req.file });
res.send("done");
});
From the docs:
.single(fieldname):
Accept a single file with the name fieldname. The single file will be stored in req.file.

ran into an error trying to upload multiple images to AWS using Node js

I am trying to upload multiple images to when a user creates a center which is a model, and because I want to have control over the images it has its own model called media.
// Create an event center
router.post('/api/center', isVerified, upload.array('images', 15), async (req, res) => {
const files = req.files.buffer
const center = new Center({
...req.body,
owner: req.user._id,
isOpen: true,
})
console.log("initialized center")
try {
files.forEach(async (file) => {
const buffer = await sharp(file)
.jpeg({
quality: 100,
chromaSubsampling: '4:4:4',
force: true
})
.toBuffer()
const params = {
Bucket: process.env.AWS_BUCKET_NAME,
Key: `${uuidv4()}.jpeg`,
Body: buffer
}
console.log("about to upload to s3")
const data = await s3.upload(params).promise()
const med = new Media({
url: data.Location,
owner: req.user._id
})
await med.save()
console.log(`${med.url} saved`); //added check to see if photo uploaded
center.media.addToSet(med.id)
})
console.log("upload completed")
await center.save()
console.log("saved")
res.status(201).send(center)
} catch (e) {
console.log("failed", e);
res.status(500).send(e)
}
})
when I try to create a center and including images, I run into an error
Server is up on port 3000
initialized center
failed TypeError: Cannot read property 'forEach' of undefined
at D:\odede\Documents\Nodejs\eventCenter\src\routers\center.js:24:26
at Layer.handle [as handle_request] (D:\odede\Documents\Nodejs\eventCenter\node_modules\express\lib\router\layer.js:95:5)
at next (D:\odede\Documents\Nodejs\eventCenter\node_modules\express\lib\router\route.js:137:13)
at Array.<anonymous> (D:\odede\Documents\Nodejs\eventCenter\node_modules\multer\lib\make-middleware.js:53:37)
at listener (D:\odede\Documents\Nodejs\eventCenter\node_modules\on-finished\index.js:169:15)
at onFinish (D:\odede\Documents\Nodejs\eventCenter\node_modules\on-finished\index.js:100:5)
at callback (D:\odede\Documents\Nodejs\eventCenter\node_modules\ee-first\index.js:55:10)
at IncomingMessage.onevent (D:\odede\Documents\Nodejs\eventCenter\node_modules\ee-first\index.js:93:5)
at IncomingMessage.emit (events.js:314:20)
at IncomingMessage.EventEmitter.emit (domain.js:486:12)
at endReadableNT (_stream_readable.js:1244:12)
at processTicksAndRejections (internal/process/task_queues.js:80:21)
please what could be wrong, or what could I be missing?
Since you're passing file directly to sharp, you probably meant to map files to the buffers:
const files = req.files.map(file => file.buffer)

Multer unexpected field error handling

The route with my multer middleware goes something like this.
router.post('my-route-path', multer.single('file'), controllerFunc)
The multer function I have defined is to allow a single file uploaded to the file system. Everything works fine, the issue is if I have define the field name to be file If in my client request I set the field name to be file it works great. But if I give it xyz then it throws an error. Which it should the problem is I can't seem to catch that error, in my catch(e) block of my promise.
This is the error I get
Error: Unexpected field
at makeError (F:\Servup\chat\node_modules\multer\lib\make-error.js:12:13)
at wrappedFileFilter (F:\Servup\chat\node_modules\multer\index.js:40:19)
at Busboy.<anonymous> (F:\Servup\chat\node_modules\multer\lib\make-middleware.js:114:7)
at emitMany (events.js:146:13)
at Busboy.emit (events.js:223:7)
at Busboy.emit (F:\Servup\chat\node_modules\busboy\lib\main.js:38:33)
at PartStream.<anonymous> (F:\Servup\chat\node_modules\busboy\lib\types\multipart.js:213:13)
at emitOne (events.js:115:13)
at PartStream.emit (events.js:210:7)
at HeaderParser.<anonymous> (F:\Servup\chat\node_modules\dicer\lib\Dicer.js:51:16)
at emitOne (events.js:115:13)
at HeaderParser.emit (events.js:210:7)
at HeaderParser._finish (F:\Servup\chat\node_modules\dicer\lib\HeaderParser.js:68:8)
at SBMH.<anonymous> (F:\Servup\chat\node_modules\dicer\lib\HeaderParser.js:40:12)
at emitOne (events.js:115:13)
at SBMH.emit (events.js:210:7)
The current implementation that I tried in my catch block was this. (this doesn't work)
catch(e => {
if (e === 'Unexpected field') {
// catch that error here
}
});
You can catch an unexpected field error by doing this
url: https://www.npmjs.com/package/multer
var upload = multer().single('avatar')
app.post('/profile', function (req, res) {
upload(req, res, function (err) {
if (err) {
// An error occurred when uploading
return
}
// Everything went fine
})
})

How to search via elasticsearch in Node.js?

I have indexed data from firebase via elasticSearch .
And Its Working Properly .
Now I am Searching data via firebase below cloud function :
exports.searchIt = functions.database.ref('/search/{key}')
.onUpdate(event => {
let key=event.params.key;
let elasticSearchConfig = functions.config().elasticsearch;
const esClient = new elastic.Client({
host: 'http://35.198.221.164',
log: 'error'
});
console.log('client Created');
let searchBody = {
size: 20,
from: 0,
query: {
match_all: {}
}
};
esClient.search({index: 'offers', body: searchBody})
.then(results => {
console.log('Successfully Entered');
results.hits.hits.forEach(
(hit, index) => console.log(hit)
)
})
.catch(console.error);
});
But this gives error below :
textPayload: "{ Error: Not Found at respond
(/user_code/node_modules/elasticsearch/src/lib/transport.js:307:15) at
checkRespForFailure
(/user_code/node_modules/elasticsearch/src/lib/transport.js:266:7) at
HttpConnector.
(/user_code/node_modules/elasticsearch/src/lib/connectors/http.js:159:7)
at IncomingMessage.bound
(/user_code/node_modules/elasticsearch/node_modules/lodash/dist/lodash.js:729:21)
at emitNone (events.js:91:20) at IncomingMessage.emit
(events.js:185:7) at endReadableNT (_stream_readable.js:974:12) at
_combinedTickCallback (internal/process/next_tick.js:80:11) at process._tickDomainCallback (internal/process/next_tick.js:128:9)
And on changing host to any other it still create client.
Why is this happening?

Resources