I've an API in Node and Express which is receiving a file from a the client (Postman in development) and I use multer to get the file in memory like this:
router.post('/api/v1/upload', contrl.upload, contrl.uploadFile);
and then in my controller:
exports upload = multer({ storage: multer.memoryStorage() }).single('file');
Now I can access the file with req.file.buffer, but then I want to send this same file to another API.
I'm using request-promise-native so this would be something like this:
const rp = require('request-promise-native')
exports.uploadFile = (req, res) => {
const options = {
method: 'POST',
uri: `${uri}`,
form: {
file: req.file.buffer
}
}
rp(options)
.then(parsedBody => {
return res.status(201).send(parsedBody);
})
.catch(err => res.status(400).send(err));
}
I removed some other params for simplicity, but this is not working, probably because Node doesn´t know how to handle the info inside req.file.buffer.
EDIT. Ok after some tests I tried to make this work with a real file instead of using multer memoryStorage. So I got this:
exports upload = multer({ dest: 'uploads/' }).single('file');
to save the file to disk, and then
const request = require('request')
exports.uploadFile = (req, res) => {
const formData = {
file: fs.createReadStream('uploads/' + req.file.filename)
}
const options = {
url: `${uri}`
formData
}
request.post(options, (err, response, body) => {
if (err) return res.status(400).send(err);
return res.status(201).send(response);
});
}
And it works! But then when I change to memoryStorage in multer and I use file: req.file.buffer instead, it does not work.
EDIT2: I also tried to send the file as a stream when in memory, so I tried this
const bufferStream = new stream.PassThrough();
bufferStream.end(req.file.buffer);
and then passing it in the formData with file: bufferStream but also not working.
How can I achieve this? Thanks
I had the same problem a few times and always end up with a bad solution. thank you all for this post. Here is my solution with aixios in case someone can use it
//First use form-data
const FormData = require('form-data') ;
//use axios
const axios = require('axios') ;
//Note is very important passing contentType and filename
//options
let form = new FormData() ;
//consider req.file is the file coming from multer
form.append('file',req.file.buffer,{
contentType:req.file.mimetype,
filename:req.file.originalname
}) ;
//now do a post request with axios
// personally I like the use of async-await for promises but
//then() catch() will work just fine
let response = await axios.post('API_URL', form, {
headers: form.getHeaders()
});
// whatever you need with response ex.
console.log(response.data)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With