Hello,
In my example here: https://stackblitz.com/edit/angular-92pdva-pkkzwk?file=app%2Ftable-sorting-example.ts
I am trying to parse a JSON string, and load it into Element data array.
I also adjusted Element interface properties and data table in the template file accordingly.
For some reason Table is not sorting "Title" column correctly. After sorting "Title" column in asc. order, I would expect "a first record" to be on the top.
Any idea why this happens?
Thanks for this issue. I tried looking into it, but it looks this works as expected.
In descending order (arrow down): lr ja test2 is first, as it is greater than a first record.
In ascending order (arrow up): lr ja test2 is last as a first record is smaller than a first record.
The others FA test and JA test are both lexicographical smaller than lr a test2 and lr ja test2.
Hi @devversion, thanks for your reply.
I just tried lexicographical string comparison in JS, and I got different results.
Please see the following example:
var arr = ["FA test", "lr ja test2", "a first record", "JA test"];
arr.sort(function(a, b) {
return a.localeCompare(b);
});
console.log(arr);
Hi @cik10p. Thanks for getting back to this so quickly. I must say that I'm personally also confused about this behavior and I'd also expect a first record to be the first element (as it starts with a).
In the sort directive we currently rely on the basic ECMAScript relational operators. i.e.
["FA test", "lr ja test2", "a first record", "JA test"]
.sort((a, b) => a === b ? 0 : (a < b) ? -1 : 1)
// (4)聽["FA test", "JA test", "a first record", "lr ja test2"]
This behaves different to localeCompare as you showed in your example. The order from localeCompare matches my personal preferred order (based on my current locale). The ECMAScript relational operators are described to use a "simple" lexicographical sort for two string operands.
See: https://www.ecma-international.org/ecma-262/5.1/#sec-11.8.5 and Note 2.
Obviously that described order is based on the Unicode numerical code points, but not on the locale-specific dictionary. That was my thinking when I said that this works as intended (as the written logic matches the table output).
The question now is whether want to actually consider using localeCompare by default for string operands, or not. I could imagine us doing that, but then I assume we'd also need to add support proper internationalization. What do you think?
cc. @andrewseguin for thoughts on this.
Hi again @devversion, and @andrewseguin
Appreciate much better explanation of situation, I understand the problem now. And now it makes sense.
Speaking of how it should be, if my customer comes to me and shows me that there is an error, I must fix it, one way or another. I guess it's up to your QA to decide whether you should stick with ECMAScript relational operators in this particular scenario. But in my understanding this is wrong, and this should be changed.
But I don't know implementation details, and how exactly this could impact the performance. But with some additional testing data (that you just received from me) you should be able to make the right decision :)
We all love when you have an option, so in my opinion it would be great if I could add an additional directive along side 'mat-sort-header' that would allow me to choose a specific sorting per column. Of-course include additional info in documentation, on 2 different scenarios and warn about possible risks of each.
Hope it's OK answer for you :) let me know what you think.
Cheers,
Dmitrij
You can define your own sorting algorithm by providing your own function to the data source.
The function you want to set is sortData, which takes the data array and the sort and returns the sorted values.
I'm not sure why this case is proving to be an oddball, but you should be able to create a function that matches your needs.
https://material.angular.io/components/table/api#MatTableDataSource
Here's a reproduction of setting your own sortData: https://stackblitz.com/edit/angular-92pdva-qxlj2b?file=app/table-sorting-example.ts
Hello @andrewseguin and @devversion,
Thanks for great example, appreciate your help allot guys! :)
I guess I will settle with your solution for now. Surely this is OK solution, as it provides a way to utilize pretty much any sorting logic one might need.
Sadly this increases amount of code I must maintain, I am sure you understand the hassle. Would love to see a more elegant solution/option in future. Since there was nothing magical about my example and my goal here.
But again, thanks allot for the help! Hope not gonna encounter any more issues like this, but anyway really happy for you guys, and appreciate great work you do! :)
Cheers,
Dmitrij
Closing this since MatTableDataSource (despite the name) is not really meant to cover all use-cases, but is instead meant to be useful for simple scenarios (client arrays with basic sort/page/filter). For more advanced scenarios, we recommend making custom data sources.
Most helpful comment
Here's a reproduction of setting your own
sortData: https://stackblitz.com/edit/angular-92pdva-qxlj2b?file=app/table-sorting-example.ts