Retrieve data from a ReadableStream object?
Solution 1
In order to access the data from a ReadableStream
you need to call one of the conversion methods (docs available here).
As an example:
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(function(response) {
// The response is a Response instance.
// You parse the data into a useable format using `.json()`
return response.json();
}).then(function(data) {
// `data` is the parsed version of the JSON returned from the above endpoint.
console.log(data); // { "userId": 1, "id": 1, "title": "...", "body": "..." }
});
EDIT: If your data return type is not JSON or you don't want JSON then use text()
As an example:
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(function(response) {
return response.text();
}).then(function(data) {
console.log(data); // this will be a string
});
Hope this helps clear things up.
Solution 2
Some people may find an async
example useful:
var response = await fetch("https://httpbin.org/ip");
var body = await response.json(); // .json() is asynchronous and therefore must be awaited
json()
converts the response's body from a ReadableStream
to a json object.
The await
statements must be wrapped in an async
function, however you can run await
statements directly in the console of Chrome (as of version 62).
Solution 3
res.json()
returns a promise. Try ...
res.json().then(body => console.log(body));
Solution 4
Little bit late to the party but had some problems with getting something useful out from a ReadableStream
produced from a Odata $batch request using the Sharepoint Framework.
Had similar issues as OP, but the solution in my case was to use a different conversion method than .json()
. In my case .text()
worked like a charm. Some fiddling was however necessary to get some useful JSON from the textfile.
Solution 5
Note that you can only read a stream once, so in some cases, you may need to clone the response in order to repeatedly read it:
fetch('example.json')
.then(res=>res.clone().json())
.then( json => console.log(json))
fetch('url_that_returns_text')
.then(res=>res.clone().text())
.then( text => console.log(text))
Related videos on Youtube
noob
Updated on July 08, 2022Comments
-
noob almost 2 years
How may I get information from a
ReadableStream
object?I am using the Fetch API and I don't see this to be clear from the documentation.
The body is being returned as a
ReadableStream
and I would simply like to access a property within this stream. Under Response in the browser dev tools, I appear to have this information organised into properties, in the form of a JavaScript object.fetch('http://192.168.5.6:2000/api/car', obj) .then((res) => { if(res.status == 200) { console.log("Success :" + res.statusText); //works just fine } else if(res.status == 400) { console.log(JSON.stringify(res.body.json()); //res.body is undefined. } return res.json(); })
-
noob over 7 years@FrancescoPezzella Thanks for the response. I have tried
response.Body.json()
, but I am getting italic TypeError: Cannot read property 'json' of undefined italic . Is this because the bodyUsed property is also set to false? However I can view this body under the response tab in browser developer tools. There is an error message which I'd like to retrieve. -
Ashley 'CptLemming' Wilson over 7 yearsSo your issue is purely related to the error 400 condition? What happens if you change the handler to
console.log(res.json());
? Do you see the data you are expecting? -
guest271314 over 7 years@noob Are you trying to read the response as a stream if
res.status == 200
? -
Lucio almost 6 yearsIs it just me or that documentation is plain wrong? I did fix it with the solutions on this answers though.
-
xaddict over 3 yearsI know it has been a while but for the sake of keeping stackoverflow great, please just accept the right answer. The one with over 200 upvotes.
-
-
noob over 7 yearsThanks for the response. I have tried this and am still getting the same error where res.body is undefined. I am able to retrieve the status however in first then() function with res.status. It seems that only the body is a ReadableStream object. It does seem to have a property locked, which is set to true?
-
Ashley 'CptLemming' Wilson over 7 yearsWhere are you trying to access
res.body
(this isn't part of my example)? Can you share some sample code in your original question to make it clearer where your problem might be. -
noob over 7 yearsI tried accessing res.body from the json response that was returned in first .then() function. I have added a sample to my original question for more clarity. Thanks!
-
edencorbin over 7 yearsAwesome, using react and request native, and wondering what in the world to do with a ReadableStream, and this did the trick. ++
-
reectrix over 6 yearsI tried this, and it printed out the Promise instead of the body.
-
Cameron Hudson almost 6 yearsThank you! This worked for me. I am sending an Illuminate http response from my Laravel server with a simple
return $data;
. I was finally able to read this response in the browser withfetch(...).then(response => response.text()).then(data => console.log(data));
-
abelito about 5 yearsJust a headsup, seems like a no-brainer, but make sure the backend you're hitting is actually providing valid JSON! Definitely not speaking from experience.
-
Óscar Gómez Alcañiz almost 5 yearsTry to chain the
.then
calls:fetch(...).then(res => res.json()).then(data => console.log(data))
-
Óscar Gómez Alcañiz almost 5 yearsThe chaining
then
helps you retrieve the final resolved value (thebody
). Nesting them prevents you from being able to get thebody
value without a callback or some mechanism of the sort. Imagine this:let body = await fetch(...).then(res => res.json()).then(data => data)
. This wouldn't work in the nested way. To check forresponse.status
you can alwaysthrow
an exception inside the firstthen
, and add acatch
to the whole promise chain. -
Azurespot over 4 yearsWhat if the response of the ReadableStream is an image?
-
Stefan Rein over 4 years@Azurespot It depends on what you want to do with the Image. You could call one of these methods developer.mozilla.org/en-US/docs/Web/API/Body, for example
const imageBlob = await response.blob();
and thenconst objectUrl = URL.createObjectURL(imageBlob); htmlImageElement.src = objectUrl;
. The returned URL is released automatically when the document is unloaded. But if your page has dynamic use, you should release it explicitly by calling window.URL.revokeObjectURL(objectUrl). Or use a FileReader. -
Sanchit Batra almost 4 yearsSometimes the real answer for you really is #2 haha, it makes sense why they'd make .json() asynchronous but it wasn't immediately obvious
-
Nash Worth over 3 yearsAGREE. Preferred in enterprise environment. : )
-
lumayara over 3 yearsThis helped me so much! Thank you!
-
PhilosophOtter over 3 yearsthank you so so so much for this resposne! I was bashing my face against everything not understanding all this "readable stream" api documentation and its all about chunks & text files and crap im not using. this worked! I haven't done backend work in over a year so i'm so rusty, this looks like what I used to learn/write and I knew I was forgetting something like this - this was it!
-
KyleMit about 3 yearsYay for CityMarket.md <3
-
Alex W over 2 yearsLink is broken, try this: developer.mozilla.org/en-US/docs/Web/API/ReadableStream
-
Dan Barron about 2 yearsThis worked for me and is so simple. Thanks!