Accessing JSON object within an object

I’m working with an API that shows data for cryptocurrencies called CryptoCompare. I’m a React noob but I’ve managed to use Axios to do the AJAX request. However I’m having trouble accessing the JSON elements I want.

Here’s what the JSON looks like: https://min-api.cryptocompare.com/data/all/coinlist

Here is my request:

import React, { Component } from 'react';
import './App.css';
import axios from "axios";
var NumberFormat = require('react-number-format');

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      coinList: []
    };
  }



  componentDidMount() {
    axios.get(`https://min-api.cryptocompare.com/data/all/coinlist`)
    .then(res => {
      const coins = res.data;
      //console.log(coins);
      this.setState({ coinList: coins});
    });
  }



// Object.keys is used to map through the data. Can't map through the data without this because the data is not an array. Map can only be used on arrays.
  render() {
    console.log(this.state.coinList.Data);
    return (
      <div className="App">
        {Object.keys(this.state.coinList).map((key) => (
          <div className="container">
            <span className="left">{key}</span>
            <span className="right"><NumberFormat value={this.state.coinList[key].CoinName} displayType={'text'} decimalPrecision={2} thousandSeparator={true} prefix={'$'} /></span>
          </div>
        ))}
      </div>
    );
  }
}

export default App;

I am able to output some JSON using console.log(this.state.coinList.Data);. It outputs the JSON object, but I am unable to console.log properties of the object itself.

How would I, for example, output the CoinName property of the first element 42?

console.log(this.state.coinList.Data.CoinName doesn’t work

nor does console.log(this.state.coinList.Data[0].CoinName etc…

I don’t think it’s a React problem, you have probably just made a mistake with the structure of the JSON response if I’m not mistaken.

I haven’t tested your code but I did have a look at the JSON response, but I think the problematic line in your code is:

{Object.keys(this.state.coinList).map((key) => (
    // ...
}

This returns the original response and isn’t the object containing the data for the coins. If you change it to the following then your code will (probably) work:

{Object.keys(this.state.coinList.Data).map((key) => (
    // ...
}

As an aside, you may consider moving the JavaScript logic outside of return(), it will make your code much easier to read and maintain particularly if you have slightly larger components or require a bit more data processing than usual:

  render() {
    const coins = Object.keys(this.state.coinList.Data).map((key) => (
        <div className="container">
            <span className="left">{key}</span>
            <span className="right"><NumberFormat value={this.state.coinList[key].CoinName} displayType={'text'} decimalPrecision={2} thousandSeparator={true} prefix={'$'} /></span>
        </div>
    ));

    return (
      <div className="App">
        {coins}
      </div>
    );
  }

EDIT: it’s worth noting that the fetch API works well for me in a lot of cases and you may not need axios as an extra dependency. If you are using create-react-app then I think fetch() is polyfilled.

I hope that helps. :slight_smile:

1 Like

You were right about the JSON issue, good eye.

Thanks for also pointing out the separation of concerns/separating logic from display. As a React noob that’s one of the trickier aspects of React.

You’re welcome. :slight_smile:

And as far as I can tell what you wrote is perfectly valid react code, it’s just a suggestion! If you are going to be using more React and not just for this project, I think this article is worth reading and will save you time in the long run. Good luck!