Good day to everyone.
I'm using Multer 2.0.0-rc.2. I created a variable that stores the stream of my file that I'm sending from Postman to my API:
const getStream = require("get-stream");
const multerStream = await getStream(req.file.stream);
I logged it, and the stream is definitely there. Wonderful. But then I have to upload this file to imgur API. How should I do it? The post request below works if I put a direct link to any image file on the internet instead of WHAT GOES HERE?. But how to upload the file from my stream? I want to use streams since it's better than temporary storing the file on disk or entirely in the memory. Thank you in advance, hope somebody could help me :)
const imgurResponse = await axios.post(
https://api.imgur.com/3/upload,
{ image: WHAT GOES HERE? },
config
);
I'm not sure of the specifics of the imgur API, but getStream's promise resolves with the content of the stream, not the stream itself.
So your multerStream variable is actually the file's data represented as a string. Check yourself with typeof multerStream. That means that you're actually buffering all the stream's data into memory. That's what getStream does, it collects all a stream's data into memory and then returns it to you.
So what you're sending as the body is an object with the key image with a type of String. That's not usually how file uploads work.
Make sure that imgur isn't expecting a a FormData as the request body. (Peeking at their docs, it seems that is what they're expecting)
You should be able to pass a stream as a representation of a file to a form, something like myFormData.append('image', req.file.stream). You likely will need to install form-data.
I'm not sure of the specifics of the imgur API, but
getStream's promise resolves with the content of the stream, not the stream itself.So your
multerStreamvariable is actually the file's data represented as a string. Check yourself withtypeof multerStream. That means that you're actually buffering all the stream's data into memory. That's what getStream does, it collects all a stream's data into memory and then returns it to you.So what you're sending as the body is an object with the key
imagewith a type ofString. That's not usually how file uploads work.Make sure that imgur isn't expecting a a
FormDataas the request body. (Peeking at their docs, it seems that is what they're expecting)You should be able to pass a stream as a representation of a file to a form, something like
myFormData.append('image', req.file.stream). You likely will need to installform-data.
Ok, I did this:
const FormData = require("form-data");
const form = new FormData();
form.append("image", req.file.stream)
Then I did my request like this:
const imgurResponse = await axios.post( https://api.imgur.com/3/upload, { image: form.image + ".jpg" }, config );
But again I got "Request failed with status code 400". Bloody hell, this is so frustrating for me.
I tried to set "content-type" both "application/json" and "multipart/form-data", but neither fixes it. I checked the response and saw that the field "image" in it was "undefined.jpg"
Where am I making a mistake?
So the form should be the entire request body, I got this working doing the following:
const imgurForm = new FormData();
imgurForm.append('image', req.file.stream);
const result = await axios.post(
'https://api.imgur.com/3/upload',
imgurForm,
{
headers: {
Authorization: `Client-ID ${CLIENT_ID}`,
...imgurForm.getHeaders(),
},
}
);
I'm passing the entire FormData as the body. Any fields you need to send to imgur should be set on the form. Finally, I'm pulling the headers from the form using the .getHeaders() method of form data.
If you want to set the name of the file when using formdata and streams, pass it as the third argument:
imgurForm.append('image', req.file.stream, 'myFile.jpg');
// alternatively, get it from multer
imgurForm.append('image', req.file.stream, req.file.originalName)
And if you need to pass any other fields to imgur, set them on the form:
imgurForm.append('description', 'here is my image description text')
I'm gonna close this because it seems to not relate to multer anymore but the Imgur API.
Multipart stuff can be confusing, which is why multer is so useful for receiving these uploads! Sending them from node is it's own special kind of pain. If you run into more issues, I'd suggest searching for tutorials about sending multipart forms w/ Node.js using axios or whatever your request library of choice is.
Thank you very much! Will do it this way first thing tomorrow!馃檹