0

I have two problems. First, when fetching data from API I get it only after the interval, which I set. However, first call I need to get immediately. Second, when I converting received data into numbers, I lose part of numbers, as example instead receiving 11,518.6217 I get only 11. Can anybody help me, please.

    class Currencies extends Component {
      state = {
        inputField: 0,
        exRates: 0,
      };
      componentDidMount() {
        try {
          setInterval(async () => {
            const res = await fetch(
              "https://api.coindesk.com/v1/bpi/currentprice.json"
            );
            const exRates = await res.json();
            console.log(exRates.bpi);
            this.setState({ exRates: exRates.bpi });
          }, 6000);
        } catch (err) {
          console.log(err);
        }
      }
      BTCChangeHandler = (event) => {
        this.setState({ inputField: event.target.value });
      };
      render() {
        const exRates = this.state.exRates;
        const currData = Object.values(exRates).map((value) => value.rate);
        const rates = currData.map(parseFloat);
        console.log(rates);
        return (
          <div>
            <input
              type="number"
              placeholder="Enter BTC value"
              onChange={this.BTCChangeHandler}
            />
            <Currency name="USD" value={this.state.inputField * rates[0]} />
            <Currency name="GPB" value={this.state.inputField * rates[1]} />
            <Currency name="EUR" value={this.state.inputField * rates[2]} />
          </div>
        );
      }
    }
    export default Currencies;
R J
  • 41
  • 5

3 Answers3

0

I'm using setInterval, but on first call I need to call it immediately

You should call it manually, as well as calling it on setInterval.

let dofetch = async () => {
  const res = await fetch(
    "https://api.coindesk.com/v1/bpi/currentprice.json"
  );
  const exRates = await res.json();
  console.log(exRates.bpi);
  this.setState({ exRates: exRates.bpi });
}
setInterval(dofetch, 6000);
dofetch()

I lose part of numbers, as example instead receiving 11,518.6217 I get only 11

Your string numbers are formatted with ,, you should remove it before passing them to parseFloat function.

parseFloat('11,518.6217') // 11
parseFloat('11,518.6217'.split(',').join('')) // 11.518.6217

So change:

currData.map(parseFloat);

to:

currData.map(s => parseFloat(s.split(',').join('')));
yaya
  • 7,675
  • 1
  • 39
  • 38
  • This is not correct as you now have two decimal seperators in the string. – FunkeyFlo Aug 05 '20 at 13:17
  • 1
    Wouldn't `+'11,518.6317'.replace(/,/g, '')` be shorter (and more efficient) way? – Yevhen Horbunkov Aug 05 '20 at 13:18
  • @YevgenGorbunkov some beginners don't know regx, so it's more readable for them. – yaya Aug 05 '20 at 13:20
  • @yaya : I would say, learning new (*appropriate*) tools rather than sticking to old (and inefficient in certain scenarios) ones is what makes them *developers* rather than one-trick-pony – Yevhen Horbunkov Aug 05 '20 at 13:23
  • @YevgenGorbunkov but regx is advanced stuff. just look at this question, he is using `setTimeout`, `react`, `.map`, ... without knowing how to debug. i recommend them to learn step by step , not using alot of stuffs (regx, react, es6, ...) while not knowing the basic stuffs (how to debug). – yaya Aug 05 '20 at 13:26
  • @RJ No problem. it's better to upvote the helpful answers instead of comment, because when you put a thanks comment like now, the only person who gets the notification is the one who own the answer (me). – yaya Aug 05 '20 at 14:38
0

This is a locale issue. The Api provides values that have a , to indicate thousands and a . to indicate decimals. Your client probably uses the opposite. First you will have to convert the string to your clients locale and then you can parse it as a number.

You can either use a library such as mentioned in this post. Or you can create your own function that switches the symbols.

FunkeyFlo
  • 295
  • 1
  • 6
0

you can try setTimOut instead of setInterval then return a promise which fetch the data in api rest

  • but the question was another thing. he asked how to get the result immediately, as well as on `setInterval`. – yaya Aug 05 '20 at 13:36