Welcome to the place to discuss the coding exercise with the top 5 altcoins.
Retrieve the top 5 coins, their tickers and their prices from Coinpaprika. Batch the requests using Promise.all.
Welcome to the place to discuss the coding exercise with the top 5 altcoins.
Retrieve the top 5 coins, their tickers and their prices from Coinpaprika. Batch the requests using Promise.all.
Bad solution, wanted to loop the coins:
const node = document.querySelector(".coins");
let list =[];
Promise.all([
axios.get(âhttps://api.coinpaprika.com/v1/tickers/btc-bitcoinâ),
axios.get(âhttps://api.coinpaprika.com/v1/tickers/eth-ethereumâ),
axios.get(âhttps://api.coinpaprika.com/v1/tickers/usdt-tetherâ),
axios.get(âhttps://api.coinpaprika.com/v1/tickers/xrp-xrpâ),
axios.get(âhttps://api.coinpaprika.com/v1/tickers/bch-bitcoin-cashâ)
]).then(
(coinResponses) => {
const coins = coinResponses
.map(response => `
${response.data.name} (${response.data.symbol}): $${response.data.quotes['USD'].price}
`) .join(''); node.innerHTML = `
Took longer than expected but that was I forgot Promise.all()
takes an array so I was attempting to use spread and it was producing an error.
There will be quite a lot of new Coinpaprika users triggered by this course.
@mayjer, donât forget to clean up unnecessary console logs.
@andersbraath1, no worries about looping or mapping, both works. No need to go pure functional when the objective of our code is a side-effect in the form of a DOM insertion.
I could not get the loop to work, but you showed it in the solution. This API setup is golden, thank you have been looking for something like this!
Is there a way to increase the number of tickers to more than 10? I get this error: createError.js:16 Uncaught (in promise) Error: Request failed with status code 429.
Too many requests!? If I do:
const COIN_COUNT = 10;
It works.
You will get blocked due to querying too many endpoints. This is why it seems Coinpaprika encourages retrieving all coins and filtering in your application.
Stoked!
I made the parseInt update work. I must be learning!
handleRefresh = async (event) => {
// Prevent default action of submitting the form
event.preventDefault();
const updatePrice = await this.props.handleRefresh(this.props.ticker);
};
render() {
return (
<tr>
<Td>{this.props.name}</Td>
<Td>{this.props.ticker}</Td>
<Td>${parseFloat(Number(this.props.price).toFixed(4))}</Td>
{this.props.showBalance ? <Td>${this.props.balance}</Td> : null}
I reused the table of the previous exercise and tried to gather axios calls in an array.
I begin to better understand the use of codePen and its render
I tried to get cute with assigning a variable equal to the id of the top five coins in api.coinpaprika.com/v1/coins and retrieve the name, symbol, and price quotes within api.coinpaprika.com/v1/tickers using the id, but I finally settled on the easier way. Looking forward to getting better and providing a more scaleable solution. Loving the course thus far! Anyway, hereâs my code:
https://codepen.io/kapitanon/pen/PoZMpJr
I separated some concerns. componentDidMount() seemed overloaded with tasks its name does not imply.
class App extends React.Component {
state = {
apName: 'Coin Exchange',
balance: 10000,
showBalance: true,
coinData: [],
};
getIDs = async () => {
// Fetch the IDs of first COIN_COUNT items.
const repsonse = await axios.get('https://api.coinpaprika.com/v1/coins')
return repsonse.data.slice(0,COIN_COUNT).map(coin => coin.id);
}
getCoinData = async(coinIds) => {
// Retrieve coin data array for given coin id's.
const tickerUrl = 'https://api.coinpaprika.com/v1/tickers/';
const promises = coinIds.map(key => axios.get(tickerUrl + key));
return await Promise.all(promises);
}
extractPrices = (coinData) => {
// Extract prices from given coinData array
return coinData.map(function(response) {
const coin = response.data;
return {
key: coin.id,
name: coin.name,
ticker: coin.symbol,
balance: 0,
price: parseFloat(Number(coin.quotes.USD.price).toFixed(2)),
};
});
}
loadAllAPIData = async () => {
// Load API data for all items.
const coinIds = await this.getIDs();
const coinData = await this.getCoinData(coinIds);
const coinPriceData = this.extractPrices(coinData);
this.setState({ coinData: coinPriceData});
}
componentDidMount = async () => {
// hook for timing. Do this:
this.loadAllAPIData();
};
import React from âreactâ;
import â./App.cssâ;
import ExchangeHeader from â./components/ExchangeHeader/ExchangeHeaderâ;
import CoinList from â./components/CoinList/CoinListâ;
import AccountBalance from â./components/AccountBalance/AccountBalanceâ;
import axios from âaxiosâ;
//import {v4 as uuidv4} from âuuidâ;
const COIN_COUNT = 5;
export default class App extends React.Component {
state = {
balance: 10001,
showBalance : true,
coinData: [
]
}
/**
// Notes on how this all works:
// calling promise.all() will execute all the promises in the array passed
// after all that is done you get an array in this case ( coinResponses ) and this
// is passed to the then() part. this is only called once at the end of the promises.
// if there is an error the .then() is not called.
//
let coinData = [];
Promise.all( [
axios.get('https://api.coinpaprika.com/v1/tickers/' + coinData1[0].key),
axios.get('https://api.coinpaprika.com/v1/tickers/' + coinData1[1].key),
axios.get('https://api.coinpaprika.com/v1/tickers/' + coinData1[2].key),
axios.get('https://api.coinpaprika.com/v1/tickers/' + coinData1[3].key),
axios.get('https://api.coinpaprika.com/v1/tickers/' + coinData1[4].key)
]
).then(
(coinResponses) => {
console.log( "promis called ", coinResponses);
// move the responses into coinData array where we can set the state later.
for( let i = 0; i< coinResponses.length; i++) {
coinData.push(
{
key: coinResponses[i].data.id,
name: coinResponses[i].data.name,
ticker: coinResponses[i].data.symbol,
balance: 0,
price: coinResponses[i].data.quotes.USD.price
})
}; //endfor
this.setState({ coinData});
} // endThen
); //endPromisAll
}
// update the price, leave all the other things the same
handleRefresh = (valueChangedTicker) => {
const newCoinData = this.state.coinData.map(
function( values) {
let newValues = { âŚvalues }; //clone the old values (shallow copy)
if ( valueChangedTicker === newValues.ticker ) {
const randomPercentage = 0.995 + Math.random() * 0.01;
newValues.price *= randomPercentage;
}
return newValues;
});
this.setState({coinData: newCoinData});
}
// handle the clicking of the show balance button.
// we toggle it from true to false or false to true.
handleBalanceShowHide = () => {
let newShowBalance = !this.state.showBalance;
this.setState({showBalance: newShowBalance});
}
render() {
return (
<div>
<AccountBalance amount={this.state.balance} showBalance={this.state.showBalance}
handleBalanceShowHide= {this.handleBalanceShowHide} />
</div>
<CoinList coinData={this.state.coinData}
showBalance={this.state.showBalance}
handleRefresh={this.handleRefresh} />
</div>
);
}
}
https://codepen.io/scrummaciousd/pen/ZEOdNmx
I need to ask, how do you embed the codepen in a forum message?
Hey @Ciaran, hope you are well.
Is quite easy, right bottom corner on codepen editor, you have an âEmbedâ option, click on it.
If you have any more questions, please let us know so we can help you!
Carlos Z.
Took longer because i hadn´t axios defined in the beggining
HTML
<h1>Top 5 Crypto Coins</h1>
<div class = "js-container"> </div>
JS
var node = document.querySelection('.js-container');
var text = [];
Promise.all([
axios.get('https://api.coinpaprika.com/v1/tickers/btc-bitcoin'),
axios.get('https://api.coinpaprika.com/v1/tickers/eth-ethereum'),
axios.get('https://api.coinpaprika.com/v1/tickers/xrp-xrp'),
axios.get('https://api.coinpaprika.com/v1/tickers/usdt-tether'),
axios.get('https://api.coinpaprika.com/v1/tickers/ltc-litecoin')
]).then((coinResponses)=> {
const coins = coinResponses
.map(response=> '<li>$ {response.data.name} (${response.data.sympol});
${response.data.quotes ['USD'].price} </li>')
.join(' ');
node.innerHTML ='<ol> $ {coins} </ol>';
}
);