I'm trying to access the response body of an API request to Bing News (in a React component). I know the response is successful and provides an object (image from log below), but when I try to access values in the object, the log says the "data is undefined". I've tried accessing them with data.value and data ["value"], but with the same result. JavaScript is not a language I write very often in, so sorry in advance if the answer is blindingly obvious: but how do I access the values in the object?
import { useEffect, useState } from "react";
import "./StockBlock.css";
function News() {
const [data, setData] = useState();
function fetchData() {
fetch(
"https://bing-news-search1.p.rapidapi.com/news?textFormat=Raw&mkt=en-WW&headlineCount=10&category=business",
{
method: "GET",
headers: {
"x-bingapis-sdk": "true",
"x-rapidapi-host": "bing-news-search1.p.rapidapi.com",
"x-rapidapi-key": "key",
},
}
)
.then((response) => {
setData(response.json());
data && console.log("data", data.values); <<<--Error comes here
})
.catch((err) => {
console.error(err);
});
}
useEffect(() => {
const timer = setInterval(() => {
fetchData();
}, 3000);
return () => clearInterval(timer);
});
return <div></div>;
}
export default News;
When I log the whole variable I get this response:
CodePudding user response:
The issue is that response.json()
returns a Promise
, so you need to add another .then()
to that.
However a better option, in my opinion, is to make your fetchData
function an async
function so you can use the await
operator:
import { useEffect, useState } from "react";
import "./StockBlock.css";
async function fetchData() {
const url = "https://bing-news-search1.p.rapidapi.com/news?textFormat=Raw&mkt=en-WW&headlineCount=10&category=business";
const opts = {
headers: {
"x-bingapis-sdk": "true",
"x-rapidapi-host": "bing-news-search1.p.rapidapi.com",
"x-rapidapi-key": "key",
}
};
try {
const resp = await fetch( url, opts );
const data = await resp.json();
console.log( "data: %o", data );
setData( data );
}
catch( err ) {
debugger;
console.error( "fetch failed: %o", err );
}
}
function News() {
const [data, setData] = useState();
useEffect( () => {
const timer = setInterval( fetchData, 3000);
return () => clearInterval( timer );
} );
return <div></div>;
}
export default News;
CodePudding user response:
This code should work
import { useEffect, useState } from "react";
import "./StockBlock.css";
function News() {
const [data, setData] = useState();
function fetchData() {
fetch(
"https://bing-news-search1.p.rapidapi.com/news?textFormat=Raw&mkt=en-WW&headlineCount=10&category=business",
{
method: "GET",
headers: {
"x-bingapis-sdk": "true",
"x-rapidapi-host": "bing-news-search1.p.rapidapi.com",
"x-rapidapi-key": "key",
},
}
)
.then((response) => {
response.json().then((json) => {
setData(json);
data && console.log("data", data.values);
})
})
.catch((err) => {
console.error(err);
});
}
useEffect(() => {
const timer = setInterval(() => {
fetchData();
}, 3000);
return () => clearInterval(timer);
});
return <div></div>;
}
export default News;
This works because response.json
returns a Promise.