Display a response from a Fetch with HTML? - javascript

My goal is to display some data on a webpage that I have obtained with a Fetch using HTML.
My Fetch (which works) looks like this
<script>
let response = fetch(
"https://api.seatgeek.com/2/events?per_page=100&venue.city=boston&client_id=MYAPIKEY"
)
.then((response) => response.json())
.then((response) => console.log(response.events[0].title));
</script>
The code works and logs a response to the console as I've requested. Now, I'd like to show some of the response on my webpage.
My attempts have looked something like this
<center><h2 id="response"></h2></center>
<script>
let response = fetch(
"https://api.seatgeek.com/2/events?per_page=100&venue.city=boston&client_id=MYAPIKEY"
)
.then((response) => response.json())
.then((response) => console.log(response.events[0].title))
.then((response) => {
document.getElementById("response").innerHTML = response.events[0].title;
});
</script>
Context and details:
I've done some mobile dev, but I'm a noob with even basic HTML/JS interaction on web so there are some holes in my knowledge here
I'll be implementing this code injection as a code block on a Squarespace (Adirondack template, Adirondack family) but I don't think the Squarespace context should matter (the Fetch works just fine, and the code injection has been displaying other things just fine)
Error from my attempt: VM22305 about:srcdoc:8 Uncaught (in promise) TypeError: Cannot read property 'events' of undefined
I'm not committed to any particular way of displaying, I'm just trying to get the ball rolling by seeing something on the page
Thanks for your help!

Your second then is console logging and returning nothing (console.log returns undefined), so in the next then statement the response is undefined.
Change your code to:
<center><h2 id="response"></h2></center>
<script>
let response = fetch(
"https://api.seatgeek.com/2/events?per_page=100&venue.city=boston&client_id=MYAPIKEY"
)
.then((response) => response.json())
.then((response) => {
console.log(response.events[0].title);
return response;
})
.then((response) => {
document.getElementById("response").innerHTML = response.events[0].title;
});
</script>
And it should work.

If you want a chain of thens, you need to return a promise to the next one, like this:
let response = fetch(
"https://api.seatgeek.com/2/events?per_page=100&venue.city=boston&client_id=MYAPIKEY"
)
.then((response) => response.json())
.then((response) => {
document.getElementById("response").innerHTML = response.events[0].title;
});

Related

fetch pure javascript handling promises

return fetch(url)
.then(response => response.json())
.then(json => {
//everything just here?
})
.catch(err => console.log(err));
Hello guys i have a newbie question. If i want to get some data from server and manage them (create new html elements, draw some canvas) am i forced to do it this way in ".then" chain? Im asking because its quite unintuitive. And ill be glad for some example of code like this, just get data from server and create/edit some html elements. Thanks!
You can do it in more intuitive way like this
getDataFromServer(url) {
return fetch(url)
.then(response => response.json());
}
async yourMainFunction() {
const data = await getDataFromServer(url);
////everything just here with data from server?
}
one thing to note that for using await you have to make your function marked with async
You are correct, the only place the response json is avalable is in the second then() callback.
You could create a function that contains your html/canvas logic and then call that function in the response callback.
fetch(url)
.then(response => response.json())
.then(json => {
handleResponse(json) // ⭐️
})
.catch(err => console.log(err));
function handleResponse (json) {
// ⭐️ everything in here
}

No response returned from fetch

I am trying to get data from the API and it doesnot return any value. I have tried to put the apiUrl in the browser directly it works there. Even a get request via postman returns request.
fetch(apiUrl)
.then((response) => {
let data = JSON.parse(response)
console.log(data)
return data;
})
Also in Chrome debugger, there is no request in the network tab as well. I have used the same code earlier to get the response.
Calling the API with Fetch gives a promise, and converting it to JSON will return yet another promise, which you need to "await" for again. This is how it should look like
fetch(URL)
.then(response => response.json())
.then(json => console.log(json))
fetch(apiUrl)
.then((response) => {
return response.json().then( res => {
let data = res;
console.log(data)
return data;
})
})
try this

Fetching API and return Specific data

So, I am trying to fetch API from Calendarific I fetch it and I get data in console here is the code below:
btn.addEventListener('click', function fetchApi(){
fetch('https://calendarific.com/api/v2/holidays?&api_key=<myKey>&country=US&year=2019')
.then(res => res.text())
.then(data => {
//holiday.innerHTML = data;
//console.log(data);
console.log(data.holidays[0].name)
})
.catch(err => console.log(err));
// alert('click')
});
But I want to access specific data like. I want to access only the name and how can I do that? Code works fine but I faced problem to access specific data from API I tried holidays[0].name But it shows undefined What I am doing wrong here?
When receiving JSON, instead of
.then(res => res.text())
.then(...
use
.then(res => res.json())
.then(...
Also, according to calendarific documentation, there's a response key you should query first:
console.log(data.response.holidays[0].name)

Fetch res.json() Attempt to invoke intergace method 'java.lang.String...'

I'm trying to convert a response from fetch function into json format but when I do so I get an error Attempt to invoke interface method 'java.lang.string com.facebook.react.bridge.ReadableMap.getString(java.lang.String)' on a null object reference.
Here is my code snippet with fetch function:
export const fetchAllUsers = () => {
fetch('http://192.168.1.103:3000/api/userData')
.then(res => {
res.json();
//console.warn('res keys = ' + Object.keys(res))
})
}
If comment back the row with console.warn I see the following "res keys = type, status, ok, statusText, headers, url, _bodyInit, _bodyBlod, bodyUsed".
bodyUsed = false
status = 200
type = default
Why I can't convert a response into json format? Or is there any another way to do so?
UPDATE
I've added the second then but I still get the error and the console.warn('res is json') is not running:
export const fetchAllUsers = () => {
fetch('http://192.168.1.103:3000/api/userData')
.then(res => {
res.json();
//console.warn('res keys = ' + Object.keys(res));
})
.then(res => {
console.warn('res is json');
console.warn(res);
})
}
UPDATE_2
I've run fetch function with another url but still got the problem. It seems like .json() causes the error. When I'm trying to console the result of fetch in the first .then() I get json object with type, status etc keys.
export const fetchAllUsers = () => {
fetch(`http://${localIP}:${port}/api/userData`)
//.then(res => res.json())
.then(json => console.warn('JSON: ' + json))
.catch(e => console.warn('ERROR: ' + e))
}
UPDATE_3
Forgot to mention that I'm creating an Android app with React Native. For testing I'm using a physical smartphone. Chrome version there is 73.0.3683.
I've replaced my fetch query with the following:
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => console.log(json));
But still get the same error.
When I run it in https://jsfiddle.net/ it works. So the reason is hidden inside the code execution on a smartphone.
There must be more context to your problem; see the below snippet. This clearly works.
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => console.log(json));

JavaScript fetch - Failed to execute 'json' on 'Response': body stream is locked

When the request status is greater than 400(I have tried 400, 423, 429 states), fetch cannot read the returned json content. The following error is displayed in the browser console
Uncaught (in promise) TypeError: Failed to execute 'json' on
'Response': body stream is locked
I showed the contents of the returned response object as follows:
But I can still use it a few months ago.
My question is as follows:
Is this just the behavior of the Chrome browser or the fetch standard changes?
Is there any way to get the body content of these states?
PS: My browser version is Google Chrome 70.0.3538.102(正式版本) (64 位)
I met this error too but found out it is not related to the state of Response, the real problem is that you only can consume Response.json() once, if you are consuming it more than once, the error will happen.
like below:
fetch('http://localhost:3000/movies').then(response =>{
console.log(response);
if(response.ok){
console.log(response.json()); //first consume it in console.log
return response.json(); //then consume it again, the error happens
}
So the solution is to avoid consuming Response.json() more than once in then block.
According to MDN, you should use Response.clone():
The clone() method of the Response interface creates a clone of a response object, identical in every way, but stored in a different variable. The main reason clone() exists is to allow multiple uses of Body objects (when they are one-use only.)
Example:
fetch('yourfile.json').then(res=>res.clone().json())
Response methode like 'json', 'text' can be called once, and then it locks.
The posted image of response shows that body is locked.
This means you have already called the 'then', 'catch'. To reslove this you can try the following.
fetch(url)
.then(response=> response.body.json())
.then(myJson=> console.log(myJson))
Or
fetch(url)
.catch(response=> response.body.json())
.catch(myJson=> console.log(myJson))
I know it's too late but it can help someone:
let response = await fetch(targetUrl);
let data = await response.json();
I was accidentally reusing a response object, something similar to this:
const response = await new ReleasePresetStore().findAll();
const json = await response.json();
this.setState({ releasePresets: json });
const response2 = await new ReleasePresetStore().findActive();
const json2 = await response.json();
this.setState({ active: json2 });
console.log(json2);
This line:
const json2 = await response.json();
Should have been (response2 instead of the used up response1):
const json2 = await response2.json();
Reusing the previous response made no sense and it was a dirty code typo...
I also stuck into this. But this worked for me.
fetch(YOUR_URL)
.then(res => {
try {
if (res.ok) {
return res.json()
} else {
throw new Error(res)
}
}
catch (err) {
console.log(err.message)
return WHATEVER_YOU_WANT_TO_RETURN
}
})
.then (resJson => {
return resJson.data
})
.catch(err => console.log(err))
good luck
This worked for me
response.json().then(data => {
// use data
})
fetch("xxxxxxxxxx")
.then(response => response.json())
.then(data => { console.log(data)})
.catch(error => { console.log(error)})
As mentioned in the question when you're trying to use same response object, your body is about to locked due to state of the object. What you can do is that capture the value of the response object and then try to have some operation on it (.then()). Please follow the code below,
fetch('someurl').then(respose) => {
let somedata = response.json(); // as you will capture the json response, body will not be locked anymore.
somedata.then(data) => {
{
error handling (if (data.err) { ---- })
}
{
operations (else { ---- })
}
}
}
I keep getting the same error even after cloning the response. None of the answers cover the case when you need to fallback to text in case the response data is not a JSON.
In my case, the error was being thrown because first I was trying to consume the response data as a JSON, then consuming the text if the response isn't a valid JSON.
// Consuming the response data multiple times throws an error.
const response = await fetch(url, request);
try {
return await response.json();
} catch (error) {
return await response.text();
}
With the help of some of the answers, I'm now consuming the response data only once, as plain text, then try to parse it to JSON.
// This works fine because the data is being consumed only once.
const response = await fetch(url, request);
const data = await response.text();
try {
return JSON.parse(data);
} catch (error) {
console.warn(`API response is not JSON. Falling back to plain text.`, error);
return data;
}
Are you using Live Server on VSC? It may be the culprit.
In a similar situation, I reverted to Apache to serve static content and that solved the problem.

Categories

Resources