Sometimes you need to give the sorting algorithm a little nudge.

That's the case if you're displaying a table with complex objects in some columns.

Sure, the sorting algo works just fine out of the box if you're sorting simple strings and numbers. That's no problem.

But when you've got actual objects in there with multiple properties, the sort logic can get confused.

And that's when you need to help it along.

In this guide, I'll show you how to do just that.

But there's a prereq here: you already need to know how to handle basic sorting with Angular Material tables. If you don't just click that link and then come on back here.

The Problem

Let's start by looking at the problem. Suppose I've got this table:

 

Now let's also suppose that I've made the Contact column sortable.

But when I go to click the Contact column to sort it, nothing happens.

Why?

Because the Contact object is complex. It's got numerous properties like first name, last name, email address, home address, and more.

So the sorting algorithm doesn't know how to sort it.

That's why it needs a little help from its friends. In this case, you're its friends.

It's Called sortingDataAccessor

The thing you're looking for to make the custom sort happen is called sortingDataAccessor. It's a property on the MatTableDataSource class.

But unlike many other properties you're accustomed to working with, this one accepts a function.

You'll have to create the function that handles the custom sorting.

Here's what that will look like:

const sortingDataAccessor = (item, property) => {
  switch (property) {
    case 'contact': return item.contact.lastName;
    default: return item[property];
  }
};

The function accepts two parameters: item and property

Here, item represents a row in a table. Be careful not to confuse it with a column.

In Angular Material tables, you'll typically put each object in an array in its own separate row. Each column in the row displays a different property of the object.

Along those lines, the property parameter represents the property defined in the column.

So here's what's going on: if somebody sorts on the column identified by 'contact,' the application will get the contact object from the item object. Then it will get the lastName property from the contact object.

And it will sort on that lastName property. That's usually how you want to sort by people's names.

Since lastName is a simple string, the application will have not trouble sorting it.

Note that if the user sorts on anything other than contact name, the application reverts to the default sorting. But you can create custom sorting for all the columns if that's how you want to roll. Just enter a different case for each column.

Tell Your App to Use the Custom Sorting

Now all that's left to do is tell your application to use the custom sorting. You'll do that with this line:

    this.dataSource.sortingDataAccessor = sortingDataAccessor;

Bingo. All sorting will go through that function you just created.

That's really all there is to it.

Have a look at a compoment that implements this solution if you're of a mind.

Wrapping It Up

Now you can create custom sorting based on complex objects in your Angular Material table.

It's up to you at this point to take what you've learned and put it to work for you.

Have fun!

Photo by Amina Filkins from Pexels