How to Send Images to Node Js with Axios

Sending an image with axios to Node.js and then using it further

So, it should be relatively straightforward to post the image to GroupMe using Node.js and Express / Multer / Request. I've gone for Request rather than Axios on the backend since I'm more familiar with the API, but it's the same difference really.

Node.js Code (index.js)

const request = require("request");
const express = require("express");
const multer = require("multer");
const upload = multer();

const app = express();
const port = 3000;
const myToken = "" // Your API token goes here.

app.use(express.static("./"));

/* Here we take the image from the client and pass it on to GroupMe */
app.post("/uploadFile", upload.any(), (req, res) => {
sendImageToGroupMe(req, res);
});

function sendImageToGroupMe(req, res) {

const options = {
uri: "https://image.groupme.com/pictures",
body: req.files[0].buffer,
method: "POST",
headers: {
"X-Access-Token" : myToken
}
}

request(options, (err, response, body) => {
console.log("Request complete: Response: ", body);
if (err) {
console.error("Request err: ", err);
res.status(500).send("Upload failed: ", err.message);
} else {
res.status(201).send("Upload successful: GroupMe response: " + body);
}
});
}

app.listen(port);

Client side

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>

function uploadFile() {
var fileToUpload = document.querySelector('input[type=file]').files[0];
let config = {
headers : {
'Content-Type' : 'multipart/form-data'
}
}

let fd = new FormData()
fd.append('name', 'image')
fd.append('file', fileToUpload)

axios.post('http://localhost:3000/uploadFile', fd, config)
.then((response)=>{
console.log("Image posted successfully: ", response);
showOutput("Image posted successfully: " + response.data);
})
.catch(err =>{
console.error("Image post failed: ", err)
showOutput("Image post failed!");
})
}

function showOutput(html) {
document.getElementById("output").innerHTML = html;
}
</script>
</head>
<body style="margin:50px">
<input type="file" onchange="uploadFile()"><br>
<p id="output"></p>
</body>
</html>

All files go in the same directory. You can go to http://localhost:3000/ to test the index.html code, this will be served by the Node.js server as a static file.

I get a response like below from the GroupMe API:

{
"payload": {
"url": "https://i.groupme.com/157x168.png.940f20356cd048c98478da2b181ee971",
"picture_url": "https://i.groupme.com/157x168.png.940f20356cd048c98478da2b181ee971"
}
}

We'll serve locally on port 3000, so to start the server:

node index.js

NodeJS, Axios - post file from local server to another server

I'm thinking the createReadStream is your issue because its async. try this.
Since createReadStream extends the event emitter, we can "listen" for when it finishes/ends.

var newFile = fs.createReadStream(file.path);

// personally I'd function out the inner body here and just call
// to the function and pass in the newFile
newFile.on('end', function() {
const form_data = new FormData();
form_data.append("file", newFile, "filename.ext");
const request_config = {
method: "post",
url: url,
headers: {
"Authorization": "Bearer " + access_token,
"Content-Type": "multipart/form-data"
},
data: form_data
};
return axios(request_config);
});


Related Topics



Leave a reply



Submit