6

React-table is sorting decimals like this:

enter image description here

My guess is that, although I'm receiving numbers from server, react-table handles them as text. So, I modified the accessor like this:

accessor: d => Number(d.Invoice_Weight).toFixed(2)

but I keep getting the sorting wrong.

This is the code for column:

 {
                      Header: () => 
                      <DropDownMenu 
                      header={content[lang].Invoice_Weight}
                      openModal = {this.onOpenSelectColumnsModal}
                      />,
                      id: 'Invoice_Weight',
                      sortable: true,
                      accessor: d => Number(d.Invoice_Weight).toFixed(2),
                      //width: 200,
                      getProps: () => {
                        return {
                          style: {
                            textAlign: 'right'
                          }
                        }
                      },
                      show: Invoice_Weight,
                    },
Morgana
  • 337
  • 8
  • 19

3 Answers3

11

As suggested in other answers the issue is that toFixed returns a string and therefore the sorting will be done using string comparisons. However coercing back to number will not work in this case becase then you will lose trailing 0s which I'm guessing you still need.

Another solution is to use custom sorting:

accessor: d => Number(d.Invoice_Weight).toFixed(2),
sortMethod: (a, b) => Number(a)-Number(b)

You may want to refine sortMethod to handle NaNs and Infinities (if you have them) but that's the general idea

You can use this to coerce the string back to a number but only in the context of sorting without affecting the displayed value

apokryfos
  • 38,771
  • 9
  • 70
  • 114
4

My guess is this is caused by the fact that .toFixed() returns a string, so it is still sorting them as strings. So if you want to round the number and keep it as two decimal places you would have to do something like this:

accessor: d => Number(Number(d.Invoice_Weight).toFixed(2))

So convert it to a number first, round it to a two decimal place string, and then convert it back to a number again.

Chris Sandvik
  • 1,787
  • 9
  • 19
  • 1
    Chris, thank you very much! Your answer did solve the problem but the thing is that I lost the zeros (,00) of decimals so I think I'll use apokryfos' solution. Thank you both! – Morgana Jun 21 '19 at 14:47
  • 1
    No problem, after reading his answer I realized it is definitely the way to go if you did need to maintain the trailing zeros! – Chris Sandvik Jun 21 '19 at 14:49
1

Default sorting method of React Table provides sorting by string.so you have to use sortMethod props provided by React Table.

sortMethod: (a, b) => {
   a = Number(a); // Converting into number
   b = Number(b); // Converting into number
   if (a.length === b.length) {
     return a > b ? 1 : -1; // same length condition
   }
   return a.length > b.length ? 1 : -1; // comparing length of string
}
Cognisun Inc
  • 438
  • 3
  • 9