I am trying to see how browser's native webapi fetch() api works. So far I have this: Sample-Code and it works fine. But what I don't understand why is it streaming string which I have to convert to a JSON? I am not sure why would anybody even need to stream a JSON as string through a REST API? I am pretty sure I am missing something here but I am not sure how I should tell fetch() to get the response as JSON and not as a ReadableByteStream which I have to convert to a string and parse it for a JSON.
My Question is this,
Why is a string being streamed here?
How do I tell fetch() to fetch my response as text or json so that I can do response.json() or response.text() as mentioned in the docs? (FYI I tried adding a header object and creating a Header instance and passing it to fetch() neither changed my response.
All you need to do is call
fetch("https://api.github.com/users/ajainarayanan").then(res => res.json());
Here is some modified code the has the same result
fetch("https://api.github.com/users/ajainarayanan")
.then(res => res.json())
.then(res => console.log('Profile: ', JSON.stringify(res, null, 2)));
Apparently I have to do response.json() in one then handler and have the actual value in subsequent then handlers. Update-code. What I didn't realize was response.json() returned another Promise which I should handle like a promise. So console.log(response.json()) will naturally just console log a JSON object instead of my actual json. Thank your #aray12 for you answer. I didn't realize the answer until I realize .json() returned a promise.
PS: Adding this as an answer as I couldn't add this in comments.
Related
I am trying to use fetch api to bring back some data, however am unable to map it to the console once I have retrieved it.
fetch('http://jsonplaceholder.typicode.com/users', {
method: 'GET'
}).then(function(response) {
console.log(response)
response.forEach(i => console.log(i.name));
}).catch(function(err) {
console.log(`Error: ${err}` )
});
The error i get is
response.map is not a function
so I tried to parse the response,(ie var data=JSON.parse) which did not work, with the error
SyntaxError: Unexpected token o in JSON at position 1"
Interestingly, when doing the same thing with a XMLHttp request, I was required to parse it, so I would also be interested to know why the difference between these two methods of retrieving the data.
If anyone could point me in the right direction, I would be really grateful.
The Fetch API returns a response stream in the promise. The response stream is not JSON, so trying to call JSON.parse on it will fail. To correctly parse a JSON response, you'll need to use the response.json function. This returns a promise so you can continue the chain.
fetch('http://jsonplaceholder.typicode.com/users', {
method: 'GET'
})
.then(function(response) { return response.json(); })
.then(function(json) {
// use the json
});
Understanding promises is key to using the fetch API.
At the time you're trying to parse your response and loop through it, the response is actually just a promise. In order to utilize the contents of the actual response from the request, you'll have to do some promise chaining.
fetch('http://jsonplaceholder.typicode.com/users').then(function(response) {
// response.json() returns a promise, use the same .then syntax to work with the results
response.json().then(function(users){
// users is now our actual variable parsed from the json, so we can use it
users.forEach(function(user){
console.log(user.name)
});
});
}).catch(err => console.error(err));
It appears that you might be accessing the json incorrectly. You could try calling response.json() instead.
fetch('http://jsonplaceholder.typicode.com/users', {
method: 'GET'
}).then((response) => {
response.json().then((jsonResponse) => {
console.log(jsonResponse)
})
// assuming your json object is wrapped in an array
response.json().then(i => i.forEach(i => console.log(i.name)))
}).catch((err) => {
console.log(`Error: ${err}` )
});
This example is structured to match your example, but ideally, you would return response.json() on that first .then block and proceed on the next block. Here is a similar example that proceeds on the next block.
In your particular case, you can view the Fetch API as a json aware wrapper for "XMLHttpRequest"s. Main differences being that the Fetch API is simpler, functional-like, and has convenience methods. David Walsh does a reasonable comparison in his blog post, which I recommend you take a look at. Plain "XMLHttpRequest"s just pass you whatever string was sent back from the server, it has no idea it could be JSON, and thus leaves it to the user to parse the response whatever way they see fit.
So i want to fetch from my local data.js file. It looks like this:
{
product_name: [
{'name': 'hello',
'lastName': 'hello'
}, {'name': 'hi',
'lastName': 'hi'}
]
}
Is this valid JSON?
My code that I'm fetching it with looks like this :
fetch('./data.json')
.then(res=> res.json())
.then(text=> console.log(text))
After this, I get an error in my console.log. Also when I go to the network tab and click on data.json It tells me that javascript needs to be enabled, what does that mean? Thank you guys
I might be able to solve your answer.
First things
You must remember to format the JSON so that it is readable by a user, if you are currently developing your program. In production mode, you can skip this step, but it is a good practice.
Next, The JSON you have does not seem to use quotes for keys. This is a must for JSON.
If you don't like the quotes, use json5, JSON's friendlier brother.
Next,
This explains about JSON with fetch.
The Fetch API returns a response stream in the promise. The response stream is not JSON, so trying to call JSON.parse on it will fail. To correctly parse a JSON response, you'll need to use the response.json function. This returns a promise so you can continue the chain.
I see that you have done it, but are forgetting the GET method mentioned in the above post. And, use return keyword to pass the JSON to the next promise. So, your corrected JS code will be:
fetch('./data.json', { method: "GET" })
.then(res => return res.json())
.then(text => console.log(text))
I am not an expert in React, but these are some common things I can correct.
2nd Part of Question
I do not really know why it says JavaScript needs to be enabled. Maybe go to your settings and enable JavaScript? Or, if you use an ad-blocker, try disabling it once and see.
Final Words
I think I have solved a part of your question.
The Fetch API will not run when I try to get a base64 string. What am I missing?
I've tried using a standard fetch in javascript, which is fine on all other calls until it's base64. It doesn't even reach the alert.
fetch(vimgurlone)
.then(response => response.json())
.then(dataimage1 => {
alert("here");
document.getElementById("theactualdata").innerHTML = dataimage1.Content;
})
.catch(error => console.error(error))
The json response will be something like:
{ Content: "brtergbrtbrtbwrtnhtehrth4t5h......" }
I would like receive and then assign the data to a variable and then display it or at least get to the alert message in the code above. The variable/URL "vimgurlone" is valid and displays a json response when pasted into a browser, but the fetch will not run. Do I need to decode it or something? The base64 string can be quite long. Thanks.
Ignore me! the issue was the API hadn't enabled cross origin requests, the code above is fine.
Thanks for the suggestions.
I have the response after GET-request with fetch. I know that this response will return an Array. When I process it with .json() - everything is fine. But when I try to process same response with .formData()- it fails.
Here's the code:
fetch(fullPath)
.then(response => response.json())
.then((allData) => {
console.log(allData);
})
.catch((e) => console.log(e));
same one with response.formData() doesn't work.
So the question is - why we are not able to process the promise in first "then" with .formData() if the off. doc says that formData() is also acceptable method for extracting a body from the response ?
The formData() method will return an error if the response is not having the multipart/form-data type. It should have key=value entries. See this question where someone asks about designing a response with that format.
Something similar happens if you call the json() method on a response that is not valid JSON: that also triggers an exception.
Since multipart/form-data is rarely used as response content type, the formData() method is not often used either. The documentation on MDN mentions it has some use for service workers:
Note: This [method] is mainly relevant to service workers. If a user submits a form and a service worker intercepts the request, you could for example call formData() on it to obtain a key-value map, modify some fields, then send the form onwards to the server (or use it locally).
I have an API which will return an array to me.
I tried to use fetch API to get the array back.
I know that if I use fetch to acquire some data, the real body in the response is ReadableStream.
I usually to deal with it by response.json() in then function if data is json.
What I don't know is how to deal with array data?
If your API is not returning a JSON array [1,2,3] then you can use the .text function to get the raw value:
fetch('/api/text').then(function(response) {
return response.text()
}).then(function (text) {
// parse the text here how you want, for csv:
// return text.split(',')
})
Otherwise you can simply just use the .json method to get the array value.
The ArrayBuffer that you mention is to read a binary buffer, it can be useful for fetching songs or etc... If your API is returning this, I would check out the link to see what you can do. You will most likely be required to decode the buffer and how that is done is completely dependent on how your API is encoding it and I cannot answer that without more detail regarding your API response.