Series: Tables of Data

Sorting in Ember 2.0 (Replacing SortableMixin)

Published on Jul 15, 2016

We used to sort our tables of data with the SortableMixin, but now in Ember 2.0, that's gone. That's too bad for the Tables of Data app we created last year.

I tried several techniques for replacing the SortableMixin, and this is the one that worked.


Links

  • Github diff (If you have a refactor for my sorting code, PR it against this repository)

Code

export default Ember.Controller.extend({
  sortProperties: ['createdAt'],
  sortAscending: true,
  arrangedContent: Ember.computed('model', 'sortProperties', 'sortAscending', function(){
    return this.get('model').toArray().sort((a, b)=>{
      let sortProperty = this.get('sortProperties')[0];
      if(this.get('sortAscending')){
        return Ember.compare(a.get(sortProperty), b.get(sortProperty));
      } else {
        return Ember.compare(b.get(sortProperty), a.get(sortProperty));
      }
    })
  }),
  //...
})

Transcript

Last year we made a series that did some really cool stuff with Tables of Data, but it relied on the SortableMixin. But unfortunately, the SortableMixin was deprecated in Ember 1.13 and is no longer available in Ember 2.0. So we’ll need to find another way to make it work without the SortableMixin.

So first we’ll remove the SortableMixin, and now we’ll need a way to get arrangedContent. Remember arrangedContent is the property that the SortableMixin gave us, and it gave us that by looking at sortProperties and sortAscending. So we’ll start off with the simple case. We can use the Ember.computed property sort, and we’ll be getting our array to sort from the model, and then we’ll be using the sortProperties. And this kind of works. So you can see it’s sorting by Title and it’s sorting by Author. But there is a problem, and that’s that you can’t sort in a different way. It’s always sorted like this.

So this method ignores sortAscending, but even weirder, while it ignores sortAscending, it also only changes the sorting, see if it’s on the same ascending, it doesn’t change what it’s sorted by. But when you do the opposite, it changes. So this is working out really weird. As a matter of fact, the recording process of this whole episode has been really weird. I came in with three different methods, and only one of them, the most complicated, worked. So we’re going to show you that complicated method.

So here’s the method, and we’ll go over it piece by piece. By the way, if you find a less complex method that works for this use case, go ahead and put a message in the comments and if it ends up working out, I’ll include it in the code section below. Alright, so first we get... well, it’s in Ember.computed and it’s relying on the model array and the sortProperties array and the sortAscending boolean. Then we get the model array, and we actually turn it into an array since it’s actually a class that sometimes turns into an array depending on what you do to it, so we explicitly turn it into an array. And then we call sort on that array. sort gives us a function, and that function takes two arguments. Those arguments are two different things that are being compared. We’ll just call them A and B. Then in that function we’ll return a number, either -1, 0, or 1. So we return the negative number if itemA should come before itemB, and a positive number if itemB should come before itemA. And then if they’re equal it’ll return 0. We don’t have to worry about that specifically since we’ll be calling Ember.compare with the values that we specify. And that’ll return either a -1, a 0, or a 1 for us.

Anyway, so we have these arguments, and then we do a little bit of setup. We get our sortProperty property and we grab it from sortProperties and we know that because of how you set this up before there’s only ever going to be one item in sortProperties, so we just grab the first. And then if sortAscending is true, then we compare them one way, and if it’s false then we compare them the other way. Notice b and a are mixed up down here. Then we have our metaprogramming trickery where whatever we have in sortProperty, that’s what we’re going to be grabbing from a and b. So we’ll be sorting based on that property. And then we can go in and see that it works beautifully.

So there we go. There’s our sequel to the Tables of Data series, the one that’ll make it work in Ember 2.0. It’s a little bit more complex than it was before, but I think you’ll agree that a little bit of hassle is worth all the other wonderful things that we’re getting with the Ember 2.0 series.

Tables of Data

Subscribe to our mailing list