0

The issue I got is that the fetched Data from API is not saved to a variable. Please look at the fearvalue, it's being called later and the value of that is an empty string.

APY component

export let fearvalue = [];

export const fearAndGreed = () => {
    // 1. Create a new XMLHttpRequest object   
    let bitcoinAPY = new XMLHttpRequest();
    // 2. Configure it: GET-request for the URL /article/.../load    
    bitcoinAPY.open("GET", "https://api.alternative.me/fng/?limit=10&date_format=us", false)    
    bitcoinAPY.onload = () => {    
        const data = JSON.parse(bitcoinAPY.response);    
        /*const saveStaticDataToFile = () => {    
          let blob = new Blob(['Welcome'],    
          {type: 'text/plain;charset=utf-8'});    
          saveStaticDataToFile(blob, "static.txt")    
        }*/    
        console.log(data)    
        fearvalue = data.data[0];    
    }
    // 3. Send the request over the network
    bitcoinAPY.send();
}

window.addEventListener('load', fearAndGreed)

fearvalue is being called in this component and it is a blank value. Can anyone help me with saving data to this variable?

import './App.css';

import './Apy_TAPI';
import './Bitcoin Fear&Greed';
import { DataFormatting } from './DataFormatting.js';
import { fearvalue } from './Bitcoin Fear&Greed';

    import './App.css';
import './Apy_TAPI';
import './Bitcoin Fear&Greed';
import { DataFormatting } from './DataFormatting.js';
import { fearvalue } from './Bitcoin Fear&Greed';

function App() {
  const test1 = "test1"
  console.log(fearvalue)

  return (
    <div className="App">
      <header className="App-header">
        <p>
          Bitcoin analyst tool
        </p>
      </header>
      <div className='Text'>
        <h1>
          <img className="Image" src="https://alternative.me/crypto/fear-and-greed-index.png" alt="Latest Crypto Fear & Greed Index" />
        </h1>
        <h2>
          https://bitinfocharts.com/pl/bitcoin/address/1P5ZEDWTKTFGxQjZphgWPQUpe554WKDfHQ <br />
          <br />
          {fearvalue} <br />
        </h2>
      </div>
    </div>
  );
}
export default App;
nima
  • 7,796
  • 12
  • 36
  • 53
  • Exported values can be edited but they can't be overridden. Try `fearvalue.push(...data.data[0];)` instead of `fearvalue = data.data[0];` – DemiPixel Oct 12 '21 at 06:06
  • Does this answer your question? [How to return the response from an asynchronous call](https://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call) – jonrsharpe Oct 12 '21 at 06:14

1 Answers1

0

You need to save the response in a proper way. in React.js, you could use useState to create a state variable and set the response in it.

First, you need to save the response in a state variable:

import React, {useState} from 'react';

export const fearAndGreed = () => {  
    const [fearValue, setFearValue] = useState() // initialize with proper value according to your data type, it could be a empty array [] or an object {}.

    let bitcoinAPY = new XMLHttpRequest();   
    bitcoinAPY.open("GET", "https://api.alternative.me/fng/?limit=10&date_format=us", false)    
    bitcoinAPY.onload = () => {    
        const data = JSON.parse(bitcoinAPY.response);    
        setFearValue(data.data[0])  // ------> set the fearValue here
    }
    bitcoinAPY.send();
}

window.addEventListener('load', fearAndGreed)

So far, the first part is done. but you need the fearValue in the other component. to achieve this, there are some solutions like using a Global State Manager like Redux or ContextApi. without them, your implementation would be tricky since you can't use the lifting state up technique because you didn't use fearAndGreed as a child component in the parent component (App).

In such cases, you can implement a custom hook with fearAndGreed function. since the function invokes once after the page loading, you can implement this by calling the API after your components did mount.

Let's make a custom hook with the current fearAndGreed function in this way:

import {useEffect, useState} from 'react';

export const useFearAndGreed = () => {
  const [fearValue, setFearValue] = useState();

  useEffect(() => {
    let bitcoinAPY = new XMLHttpRequest();   
    bitcoinAPY.open("GET", "https://api.alternative.me/fng/?limit=10&date_format=us", false)    
    bitcoinAPY.onload = () => {    
        const data = JSON.parse(bitcoinAPY.response);    
        setFearValue(data.data[0])  // ------> set the fearValue here
    }
    bitcoinAPY.send();
  }, [])

  return fearValue;
}

Explanation:

With a few changes, fearAndGreed function becomes a custom hook useFearAndGreed. The API will call in the useEffect after the component did mount (with an empty array of dependencies). The hook will return the fearValue on every change.

Now, time to use this custom hook inside of the App component:

function App() {
 const fearValue = useFearAndGreed()

  return (
    <div>
     {fearValue}
    </div>
  );
}
export default App;

Note: I removed the other parts of implementation in the App component to simplify it. you should include your own implementation within.

Now, every time the App component did mount, the useFearAndGreed will be invoked and return the fearValue which can be saved in a constant fearValue to use in the div element.

nima
  • 7,796
  • 12
  • 36
  • 53