2

Pretty new to React and I have this issue: I want to get URL+ImageUrl from coinData.

In Vue, I would just create a method in the component:

getCoinImage: function(symbol) {
  return CRYPTOCOMPARE_API_URI + this.coinData[symbol].ImageUrl;
}

Then call the function in the view template and it would return full URL of the image I'm looking for.

How do I do it in React?

class App extends Component {

  constructor(props) {
    super(props);

this.state = {
  cryptos: [],
  coinData: {},
};
}

componentDidMount() {
 axios.get('https://api.coinmarketcap.com/v1/ticker/?limit=0')
.then(res => {
  const cryptos = res.data;
  this.setState({cryptos: cryptos});
  console.log(this.state.cryptos);

})


axios.get('https://min-api.cryptocompare.com/data/all/coinlist')
.then(res => {
const coinData = res.data.Data;
this.setState({coinData: coinData});
//console.log(coinData["BTC"].ImageUrl);
})
}

render() {
return (

    <table className="table is-striped is-narrow is-fullwidth"><thead>
        <tr>
          <td>Rank</td>
          <td>Name</td>
          <td>Symbol</td>
          <td>Price (USD)</td>
          <td>1h</td>
          <td>24h</td>
          <td>1 Week</td>
          <td>Market Cap</td>
        </tr>
      </thead>
      <tbody>{Object.keys(this.state.cryptos).map((key) => (
        <tr>
          <td>{this.state.cryptos[key].rank}</td>
          <td>{this.state.cryptos[key].name}</td>
          <td>{this.state.cryptos[key].symbol}</td>
          <td>{this.state.cryptos[key].price_usd}</td>
          <td>{this.state.cryptos[key].percent_change_1h}</td>
          <td>{this.state.cryptos[key].percent_change_24h}</td>
          <td>{this.state.cryptos[key].percent_change_7d}</td>
          <td>{this.state.cryptos[key].market_cap_usd}</td>
        </tr>
 ))};
      </tbody>
    </table>

);
}
}
1
  • Looks like this.state.cryptos is an array. Why not use this.state.cryptos.map directly? Commented Nov 17, 2017 at 7:40

3 Answers 3

2

You can write a similar function inside the component and call it when you need it, like

getCoinImage(imageUrl) {
 return `${CRYPTOCOMPARE_API_URI}${imageUrl}`;
}

Just write this like any other method(like render). Then in the place you need, you need to call it like this this.getCoinImage(this.coinData[symbol].ImageUrl). I assume you will have the required data in the variable CRYPTOCOMPARE_API_URI.

Assuming you would need it inside your map, you can call like this

<td><img src={this.getCoinImage(this.state.cryptos[key].imageUrl)} /></td>
Sign up to request clarification or add additional context in comments.

1 Comment

This is the way, I even did it before, it just had errors when there was no data from API, which I wasn't expecting. Thanks for the answer.
1

First I would only update the state once both requests have been done

async componentDidMount() {
  const res1 = await axios.get('https://api.coinmarketcap.com/v1/ticker/?limit=0');
  const res2 = await axios.get('https://min-api.cryptocompare.com/data/all/coinlist');

  this.setState({
    cryptos: res1.data,
    coinData: res2.data.Data
  });
}

Now you have access to everything you need to render your image in the render function. (I omitted some of the property for clarity purposes)

render() {
  const {cryptos, coinData} = this.state;

  return (

    <table className="table is-striped is-narrow is-fullwidth">
      <thead>
      <tr>
        <td>Symbol</td>
        <td>Image</td>
      </tr>
      </thead>
      <tbody>
      {Object.keys(this.state.cryptos).map((key) => (
        <tr>
          <td>{cryptos[key].symbol}</td>
          <td>{_.get(coinData, `[${cryptos[key].symbol}].ImageUrl`, `Not Found: ${cryptos[key].symbol}`)}</td>
          <td><img src={CRYPTOCOMPARE_API_URI + _.get(coinData, `[${cryptos[key].symbol}].ImageUrl`, '/default.png')} /></td>
        </tr>
      ))};
      </tbody>
    </table>
  );
}

6 Comments

Feels like this is the way, that's what I tried before, but then again it says TypeError: Cannot read property 'ImageUrl' of undefined
Can you debug the render function and check what is inside coinData ?
I have edited my answer to use lodash get to avoid the error. There must be some symbols that don't have a corresponding mapping in your coinData
Which also seems like it works? So, may I ask you now, how do I add the URI and embed it into <img /> tag? The nice way.
Well, it works, got the images up and running :D Never thought that no data would cause so many issues. Thanks!
|
0

Even in React you can have method in a component. Just create a method called getCoinImage in your component. Then externally keep a reference to the component and finally call it this way:

this.refs.myComponentReference.getCoinImage();

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.