0

I am building a React.js SPA, that receives data from an API with Bearer Token Authentication (so a fetch request for authentication has to be done first and the given token can be used temporarily to access the data until the auth session ends)

I can authorize and print the object to the console, but the object is not saved into the variable objectOutput in order to be accessed by the components below.

My thought is, that the asynchronous fetching causes this, and the components are rendered before the fetch() result has arrived. But I wonder how this could be fixed, so I can store it in the variable and the components can access the data as their props.

import Header from "./components/Header";
import Cardsection from "./components/Cardsection";
import Flagsection from "./components/Flagsection";
import Footer from "./components/Footer";
import MapChart from "./components/MapChart";
import { useEffect } from "react";

let api_url = "https://api-url:3000";
let batch_id = "XXX";
let api_token = "";
let objectOutput = "";

function App() {
  useEffect(() => {

    const authorize = async () => {
      var myHeaders = new Headers();
      myHeaders.append("Content-Type", "application/json");

      var raw = JSON.stringify({
        username: "username",
        password: "password",
      });

      var requestOptions = {
        method: "POST",
        headers: myHeaders,
        body: raw,
        redirect: "follow"
      };

      const res = await fetch(api_url + "/auth", requestOptions).catch(console.log("error"));
      const data = await res.json();
      api_token = data.token;
      console.log("Successful Authorization. Token: " + api_token);

      const getObject = async () => {
        var myHeaders = new Headers();
        myHeaders.append("Authorization", "Bearer " + api_token);

        var requestOptions = {
          method: "GET",
          headers: myHeaders,
          redirect: "follow"
        };

        const res = await fetch(api_url + "/get?function=readObject&args=" + batch_id, requestOptions).catch(console.log("error"));
        const data = await res.json();

        objectOutput = data;
        console.log(data);

      
      };
      getObject()

    };

    authorize();

  }, []);

  return (
    <div className="App">
      <Header
        title="Lorem Ipsum"
        description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."
      />
      <Flagsection hasFlag={objectOutput.alarmFlag} />
      <Cardsection sort={""} treatment={""} plantheight={""} harvesttime={""} />
      <MapChart/>
      <Footer />
    </div>
  );
}

export default App;```
2
  • modify this let objectOutput = ""; into this let objectOutput; Commented Feb 22, 2022 at 13:00
  • You have to use the state hook for this. (reactjs.org/docs/hooks-state.html) Just when using state, react will rerender your component. Commented Feb 22, 2022 at 13:00

1 Answer 1

1

this will help you to solve issue, as you didnt used useState hook

function App() {
    const [objectOutput, setObjectOutput] = useState();

    useEffect(() => {
  
      const authorize = async () => {              
        const res = await fetch(api_url + "/auth", requestOptions).catch(console.log("error"));
        const data = await res.json();
        api_token = data.token;
  
        const getObject = async () => {                
          const res = await fetch(api_url + "/get?function=readObject&args=" + batch_id, requestOptions).catch(console.log("error"));
          const data = await res.json();      
          objectOutput = data;
          // add below line to set object
          setObjectOutput(data);
        };
        getObject()
  
      };
      authorize();
    }, []);

if this is going to change then re render with this dependency,

useEffect(() => {}, [objectOutput]);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.