Reputation:
I've been trying to upload images to a dropbox app folder using the dropbox API v2 in my nodejs backend but every image that uploads successfully is corrupted and is only 15 bytes large and cannot be previewed from within the dropbox app folder.
This is my code;
const express = require("express");
const router = express.Router();
const fetch = require("isomorphic-fetch");
const Dropbox = require("dropbox").Dropbox;
const dbx = new Dropbox({
accessToken:
"my access token",
fetch: fetch
});
router.post("/dbx", (req, res) => {
let imageArray;
//I receive either a single image or an array of images from the front end and
//its placed in req.files by express-fileupload
if (req.files.itemImage.length) {
imageArray = [...req.files.itemImage];
} else {
imageArray = [req.files.itemImage];
}
imageArray.forEach(image => {
console.log("Image==>>",image)
dbx
.filesUpload({
path: `/${image.name}`,
contents: image
})
.then(response => {
console.log(response);
})
.catch(err => {
console.log(err);
});
});
});
Below is what a typical image that I'm sending looks like from the command console.log("Image==>>",image)
in my terminal
{ name: 'ImageName.jpg',
data:
<Buffer ff d8 ff e1 1f 39 45 78 69 66 00 00 4d 4d 00 2a 00 00 00 08 00 07 01 12 00 03 00 00 00 01 00 01 00 00 01 1a 00 05 00 00 00 01 00 00 00 62 01 1b 00 05 ... >,
size: 1865542,
encoding: '7bit',
tempFilePath: '',
truncated: false,
mimetype: 'image/jpeg',
md5: '133bda2ce6d52b4bada8ba31349c4910',
mv: [Function: mv] }
Below is the response I receive from dropbox in my terminal
{ name: 'ImageName.jpg',
path_lower: '/imageName.jpg',
path_display: 'ImageName.jpg',
id: 'id:R0fPv_de0wAAAAAAAAAAJw',
client_modified: '2019-07-08T10:21:36Z',
server_modified: '2019-07-08T10:21:36Z',
rev: '0130000000015cb7a8c0',
size: 15,
is_downloadable: true,
content_hash:
'87bfbb905f228845cfb691920551882f446042da2ef9576e26ca97c5374c3eef' }
The image name shows up correctly in the name:
field, but the image is only 15bytes in size and cannot be previewed from within the dropbox app folder. I don't understand what's going wrong hence I have no idea how to fix it. Could anyone please help me explain what I'm doing wrong? If anything about my question isn't clear, please point it out and I'll edit accordingly.
I tried sending the contents of the request as JSON.stringify(image)
and got a corrupted file 3 times bigger than what I sent, I saw a method where I'd have to first upload the images to a folder on my server then use fs commands to write the contents of each one into the request, but I don't want to have such a folder on the server, I'd rather just send the images immediately if possible.
I expect to receive a positive message from the dropbox server with the correct image size and then be able to preview the image within the dropbox app folder I created.
Upvotes: 1
Views: 2197
Reputation: 1053
Posting this as an FYI for future searchers because I had a hard time understanding this, too. Comments are welcome if this explanation can be improved.
Dropbox's /files/upload endpoint is expecting the binary data of the file (among other things). In the server-side JavaScript world, the Buffer
class is how Node deals with binary data. While you can sometimes spot a file's binary data (Buffer
object) in the request or response, the Buffer
class also comes with a variety of methods to make your own Buffer
object out of a file when you need to.
I found this article about Buffers from FreeCodeCamp to be a helpful resource.
Upvotes: 0
Reputation:
I figured it out myself. Only posting in case anyone ever faces the same problem. The contents should be changed from image, to image.data
ie rather than doing this;
dbx
.filesUpload({
path: `/${image.name}`,
contents: image
})
.then(response => {
console.log(response);
})
.catch(err => {
console.log(err);
});
it should be this
dbx
.filesUpload({
path: `/${image.name}`,
contents: image.data
})
.then(response => {
console.log(response);
})
.catch(err => {
console.log(err);
});
Upvotes: 2