You might see that the Dropbox Community team have been busy working on some major updates to the Community itself! So, here is some info on what’s changed, what’s staying the same and what you can expect from the Dropbox Community overall.
Forum Discussion
squidlauncher64
2 years agoExplorer | Level 3
downloading an image using dropbox API
Hello, I am trying to download an image from dropbox api in react native. I am getting a success code: '200' and the response says that it is ok. I have included some of the javascript code below...
- 2 years ago
Hi squidlauncher64,
You didn't account that 'blob' method doesn't return actual blob, but Promise object wrapping this blob! That's where all your troubles come from. Also when you try to stringify some object, you're getting object declaration (no actual data) and that's why appear so short result - "[object Object]" - i.e. one more mess. 🙂
You have to handle correct type in correct way. A simplistic example follows:
var reader = new FileReader(); await fetch(...all staff here...).then((r)=>r.blob()).then((b)=>reader.readAsDataURL(b)); var b64encoded = reader.result; var rawBase64 = b64encoded.slice(b64encoded.search(',')+1);
Depending on what you need either full encoded result (b64encoded) can be used or only the actual/raw base64 encoded string part (rawBase64). 😉
Hope this helps.
squidlauncher64
Explorer | Level 3
From my understanding, you are saying that the image data should be located within response.body. Is that correct? I am not using the dropbox SDK but I am interacting with the dropbox API following the instructions as described by the download http documentation. When I console.logged the response I got from the dropbox api here is what it said:
LOG {"_bodyBlob": {"_data": {"__collector": [Object], "blobId": "bbf7e68a-80ac-4c97-ae88-c2808166666e", "offset": 0, "size": 4808078}}, "_bodyInit": {"_data": {"__collector": [Object], "blobId": "bbf7e68a-80ac-4c97-ae88-c2808166666e", "offset": 0, "size": 4808078}}, "bodyUsed": false, "headers": {"map": {"accept-encoding": "identity,gzip", "accept-ranges": "bytes", "cache-control": "no-cache", "content-length": "4808078", "content-type": "application/octet-stream", "date": "Fri, 18 Aug 2023 16:38:30 GMT", "dropbox-api-result": "{\"name\": \"test.jpg\", \"path_lower\": \"/pictures/test/misc/test.jpg\", \"path_display\": \"/Pictures/Test/MISC/test.jpg\", \"id\": \"id:q1a6odEFxL4AAAAAAAAo_A\", \"client_modified\": \"2023-07-30T18:40:28Z\", \"server_modified\": \"2023-07-30T18:40:28Z\", \"rev\": \"601b8a5decf8269e55553\", \"size\": 4808078, \"media_info\": {\".tag\": \"metadata\", \"metadata\": {\".tag\": \"photo\", \"dimensions\": {\"height\": 3960, \"width\": 2640}, \"time_taken\": \"2019-07-09T10:39:36Z\"}}, \"is_downloadable\": true, \"content_hash\": \"40b0819017193231c2ba795f6f54e871623e6ac845814912fcb751749c984075\"}", "etag": "W/\"601b8a5decf8269e55553\"", "original-content-length": "4808078", "server": "envoy", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", "x-dropbox-request-id": "92f211e8055140f6bb43cc0354b0f485", "x-dropbox-response-origin": "far_remote", "x-robots-tag": "noindex, nofollow, noimageindex", "x-server-response-time": "501"}}, "ok": true, "status": 200, "statusText": "", "type": "default", "url": "https://content.dropboxapi.com/2/files/download"}
This is using the code shown in my first post. It says in the log 'bodyUsed: false' which makes me believe that response.body doesn't exist. So where would the image data be?
I did find this one sentence that might describe where the data is according to dropbox's documentation. 'The response body contains file content, so the result will appear as JSON in the Dropbox-API-Result response header.' I have checked the Dropbox-API-Result and have only found the file metaData there. There is a chance I am doing something weird in my request to dropbox and thats why the body isn't being sent? Maybe the image data is somewhere else? Any help would be greatly appreciated.
Greg-DB
2 years agoDropbox Staff
The file data would be in the response body, but not necessarily in a variable named 'response.body'. Exactly how you access it will depend on the network client you're using.
In this case, I see you're using 'fetch' as your network client, so I suggest referring to the fetch documentation I linked to in my previous message for information on how that works and how to access the data using that. For instance, it looks like using 'response.blob()' would make sense for your use case; that should contain the actual file data. I don't have context on exactly what you want to do with that data though, so what you do with it from there is up to you.
For reference, according to the documentation, the 'bodyUsed' property indicates if the body has already been read, not if it exists in the response to begin with.
For reference, the 'Dropbox-API-Result' header is a response header, which is separate from the response body. The 'Dropbox-API-Result' response header only contains the file metadata, not the file data.
- squidlauncher642 years agoExplorer | Level 3
You are correct about how the response object works, and how bodyused works. I didn't quite understand that so thank you for pointing me to the documentation. What I am trying to do is download an image from dropbox using the api that the user selects and display it for the user. I know that the image component in react native can take base64 data. I tested it with a local asset image. So the general process as I understand it is, 1) download the image from dropbox as a blob. 2) convert it to base64 3) display it on the screen for the user. I am running into problems with the second step and I want to make sure I am using this correctly. The code I am using is included below:
const startUp = async () => {method: 'POST',headers: {Authorization: `Bearer ${accessToken}`,'Dropbox-API-Arg': JSON.stringify({path: '/Pictures/Test/MISC/test.jpg'}),}});if (!response.ok) {console.error('Failed to fetch folder contents:', response.status, response.statusText);return;}else{console.log('response is ok')}const fileContentData = await response.blob()const fileData = encode(fileContentData)console.log('fileData:', fileData)Now I know that the encode function works because I use it for authentication with dropbox api. I use it for PKCE authentication for encoding the code challenge. Now when I run this I get:LOG fileData: W29iamVjdCBPYmplY3RdThis seems too short to me for a 4 mb picture. Another interesting thing is that I have changed it from the test.jpg to another image and it output the sane base64 string. I have tried using the code like this according to the documentation and I get an error stating that it cannot create a URL from the blob:const startUp = async () => {method: 'POST',headers: {Authorization: `Bearer ${accessToken}`,'Dropbox-API-Arg': JSON.stringify({path: '/Pictures/Test/MISC/test.jpg'}),}});if (!response.ok) {console.error('Failed to fetch folder contents:', response.status, response.statusText);return;}else{console.log('response is ok')}const fileContentData = await response.blob()const imageUrl = URL.createObjectURL(fileContentData);const fileData = encode(imageUrl)console.log('fileData:', fileData)Now all this code can be wrong because I am a complete novice when it comes to using apis. With this I have some questions: Why is the base64 encoded data so short? From the documentation it seems like I am getting the 'response.blob' correctly. why does the second code throw the error? Do you see anything wrong with these code snippets I have provided?On a side note: The main idea for using dropbox api directly and not using dropbox sdk is because I have interacted with spotify api in another project so I thought this would be rather straight forward just following the documentation. I have never used an sdk before and kind of seem intimidated by it. My main concern is performance. I would like the image to be ready for the user as soon as possible. Thats kind of why I am not saving the image anywhere. I am directly going from base64 encoding to image. So the question is would using the dropbox sdk improve performance? would it download the images faster and display it to the user quicker than using the dropbox api? would the dropbox sdk store the image somewhere else that i'd have to fetch i.e. a downloads folder? Where would it put the image?Thanks again for all your help!- Здравко2 years agoLegendary | Level 20
Hi squidlauncher64,
You didn't account that 'blob' method doesn't return actual blob, but Promise object wrapping this blob! That's where all your troubles come from. Also when you try to stringify some object, you're getting object declaration (no actual data) and that's why appear so short result - "[object Object]" - i.e. one more mess. 🙂
You have to handle correct type in correct way. A simplistic example follows:
var reader = new FileReader(); await fetch(...all staff here...).then((r)=>r.blob()).then((b)=>reader.readAsDataURL(b)); var b64encoded = reader.result; var rawBase64 = b64encoded.slice(b64encoded.search(',')+1);
Depending on what you need either full encoded result (b64encoded) can be used or only the actual/raw base64 encoded string part (rawBase64). 😉
Hope this helps.
- squidlauncher642 years agoExplorer | Level 3
Hello Здравко, Thank you for, your response, explaining how promises work, and sending me this code snippet. It really gave me a good place to troubleshoot and understand the issue. I was able to implement the code snippet provided and it worked! Thank you so much!
- Greg-DB2 years agoDropbox Staff
squidlauncher64 I see Здравко helpfully offered insight on the issue.
As for your other questions, no, the Dropbox SDK wouldn't improve the performance; it uses the same API endpoints. It's just meant to make it easier for you to interact with the API, but it's not necessary. It also wouldn't save the data somewhere for you; it would likewise give the data to you directly for you to use as needed.
- squidlauncher642 years agoExplorer | Level 3
Thanks again for all your help Greg-DB!
About Dropbox API Support & Feedback
Find help with the Dropbox API from other developers.
5,912 PostsLatest Activity: 4 hours agoIf you need more help you can view your support options (expected response time for an email or ticket is 24 hours), or contact us on X or Facebook.
For more info on available support options for your Dropbox plan, see this article.
If you found the answer to your question in this Community thread, please 'like' the post to say thanks and to let us know it was useful!