2.9 KiB
sorting by balance
After the last section, we are at a point we we have the intentions, actual validators and their balances. For users, we would like this display to be more usable, so here we are aiming on sorting by balance.
component
Expanding on our previous component, we now change the previously used <Balance /> component, into doing actual freeBalanceOf queries. There are 2 options here - we could also use the onChange event on the Balance component to return the display value. However here we opt for querying the raw value, transforming it and sorting with it.
class Comp extends React.PureComponent<ApiProps, State> {
...
subscribeBalances (accounts: string[]) {
const { api } = this.props;
const keyCreator = createStorageKey(balanceMethod);
const { balances, subscriptions } = this.state;
const newBalances = { ...balances };
accounts.forEach((account) => {
if (newBalances[account]) {
return;
} else {
newBalances[account] = ZERO;
}
subscriptions.push(
api.state
// Here we pass a parameter to the key generator, so it points to the correct storage entry
.getStorage(keyCreator(account))
.subscribe((balance) => {
this.setState(({ balances }: State) => {
const newBalances = { ...balances };
newBalances[account] = u8aToBn(balance, true);
return {
balances: newBalances
};
});
})
);
});
this.setState({
balances: newBalances,
subscriptions
});
}
...
render () {
const { balances, intentions, proposals, validators } = this.state;
const sortedIntentions = intentions.sort((a, b) =>
(balances[b] || ZERO).cmp(balances[a] || ZERO)
);
...
}
...
}
walk through
By now the subscription approach is known. Where things do differ however is the passing of a parameter to the key encoder. Since each balance entry is denoted by the actual account, the hashing needs to take the actual account and append it to the prefix location before making a hash that the runtime understands.
For the actual storage value, we have additional formatting on the raw value. Here we are taking the Uint8Array input and transforming it to a BN. All values in the storage are stored as little-endian-encoded values, hence passing the additional isLe flag to the Uint8Array -> BN conversion helper.
NOTE: It would make sense for future versions of the API to be expanded so additional formatting, either here or e.g. accountId are not needed. (At this early stage however the APIs are still at a too-low level to transparently take care of the transformation - although all information is contained in the params of the key being encoded)
