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

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.