Home > Back-end >  Accessing an object from a fetch request - javascript/react
Accessing an object from a fetch request - javascript/react

Time:11-14

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:

enter image description here

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.

  • Related