Reputation: 842
I am having problems in sorting my React table by clicking on columns headers for column with string values, but with the column with numerical values it's all ok. I think that I am doing wrong in sortBySymbolHandler method. I suppose that my check for strings: this.state.directionSymbol[key] === 'asc'? a[key] - b[key] : b[key] - a[key] is wrong.
import React, { Component } from 'react';
import CoinTable from '../components/CoinTable/CoinTable';
import data from '../components/Data/Data.json';
class App extends Component {
constructor(props) {
super(props)
this.state = {
data: data,
direction: {
price_usd: 'asc'
},
directionSymbol: {
symbol: 'asc'
}
}
}
sortBySymbolHandler = (key) => {
this.setState({
data: data.sort((a, b) => (
this.state.directionSymbol[key] === 'asc'
? a[key] - b[key]
: b[key] - a[key]
)),
directionSymbol: {
[key]: this.state.directionSymbol[key] === 'asc'
? 'desc'
: 'asc'
}
})
}
sortByPriceHandler = (key) => {
this.setState({
data: data.sort((a, b) => (
this.state.direction[key] === 'asc'
?
parseFloat(a[key]) - parseFloat(b[key])
: parseFloat(b[key]) - parseFloat(a[key])
)),
direction: {
[key]: this.state.direction[key] === 'asc'
? 'desc'
: 'asc'
}
})
}
render() {
return (
<div className="App">
<div className="container-fluid">
<div className="container">
<CoinTable
data={this.state.data}
sortBySymbol={this.sortBySymbolHandler}
sortByPrice={this.sortByPriceHandler}
/>
</div>
</div>
</div>
);
}
}
export default App;
Data.json is in this format:
[
{
"id": "bitcoin",
"name": "Bitcoin",
"symbol": "BTC",
"rank": "1",
"price_usd": "10406.5",
"price_btc": "1.0",
"24h_volume_usd": "9766700000.0",
"market_cap_usd": "175053324790",
"available_supply": "16821537.0",
"total_supply": "16821537.0",
"max_supply": "21000000.0",
"percent_change_1h": "-0.04",
"percent_change_24h": "-3.39",
"percent_change_7d": "-12.62",
"last_updated": "1516718960"
},
{
"id": "ethereum",
"name": "Ethereum",
"symbol": "ETH",
"rank": "2",
"price_usd": "947.841",
"price_btc": "0.0917641",
"24h_volume_usd": "3615420000.0",
"market_cap_usd": "92093645501.0",
"available_supply": "97161492.0",
"total_supply": "97161492.0",
"max_supply": null,
"percent_change_1h": "0.3",
"percent_change_24h": "-4.04",
"percent_change_7d": "-13.22",
"last_updated": "1516718952"
},
{
"id": "ripple",
"name": "Ripple",
"symbol": "XRP",
"rank": "3",
"price_usd": "1.27202",
"price_btc": "0.00012315",
"24h_volume_usd": "2597960000.0",
"market_cap_usd": "49276964438.0",
"available_supply": "38739142811.0",
"total_supply": "99993093880.0",
"max_supply": "100000000000",
"percent_change_1h": "0.83",
"percent_change_24h": "3.49",
"percent_change_7d": "-5.9",
"last_updated": "1516718941"
}
]
and CoinTable.js is like this:
import React from 'react';;
import TableRow from './TableRow/TableRow';
const coinTable = (props) => (
<table>
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th><button onClick={() => props.sortBySymbol('symbol')}>Symbol</button></th>
<th><button onClick={() => props.sortByPrice('price_usd')}>Price</button></th>
<th>%/hour</th>
<th>%/day</th>
<th>%/week</th>
</tr>
</thead>
<tbody>
{
props.data.map(row => {
const price = row.price_usd;
const formattedPrice = parseFloat(price).toFixed(2);
return (
<TableRow key={row.rank} row={row} formattedPrice={formattedPrice} />
)
})
}
</tbody>
</table>
);
export default coinTable;
Can somebody help?
Upvotes: 2
Views: 9241
Reputation: 2575
You can't subtract one string from another string.
Instead of doing:
data: data.sort((a, b) => (
this.state.directionSymbol[key] === 'asc'
? a[key] - b[key]
: b[key] - a[key]
)),
Do:
data: data.sort((a, b) => {
const asc = this.state.directionSymbol[key] === 'asc';
if (a[key] < b[key]) {
return asc ? -1 : 1;
} else if (a[key] > b[key]) {
return asc ? 1 : -1;
} else {
return 0;
}
)),
Upvotes: 1