Sorting Table Columns
I’ve been working with tables a lot these past few weeks, one task I got today was to implement a feature to sort table columns for unsorted data coming from the backend, this is how I tackled the task
NB: I’m using jsonplaceholder to mimic the API I’ll be using for fetching data
So here’s what happened so far, our return statement ran first, we draw the table, Data and TableHeaders are initially empty, so nothing is shown, then the useEffect kicks in, we fetch our data, set the Data state to JSON variable resulted from the API call and then we set TableHeaders to the keys of the first object in JSON
The result of json[0] is
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
Object.keys(json[0]) returns an array with the keys of an object so now our TableHeaders look like this
[ "userId", "id", "title", "completed" ]
setting the TableHeaders & Data states triggers a rerender, we then redraw our table and this is how it’d look like.
Next, Sorting the Columns.
I created an array called HeadersSchema which I’ll use to enforce the new order on my headers and since our tbody is drawn through the values in TableHeaders there won’t be much work needed on that end.
In the useEffect, instead of just setting the keys from the first object as they are to the TableHeaders, I’ll loop over those keys and loop over the schema when the name in my schema objects matches the Key from Object.keys(json[0]), I’ll add that Key to a new variable I’ve created in line 32 (very poor naming on my end, should have picked a better name than TableHeaders to avoid confusion😅) in that specific order I got in my schema.
At this point, TableHeaders look like this
[ empty x 2, "title", empty x 3, "id", empty x 2, "completed",empty x 78, "userId" ]
to remove those empty slots we’ll use the filter function, filter returns a new array that matches our callback function, and in the callback, we’ll return the truthy values only hence all the empty slots are undefined (falsy)
TableHeaders now look like this
[ "title", "id", "completed", "userId" ]
and that’s it! we have sorted our columns successfully in the same order provided in the schema 🥳
Lastly, we’ll handle the edge case scenarios if the same order in our schema is duplicated or if an object in our schema has no order at all 🤔
Luckily, both cases aren’t tough to handle.
const HeaderOrder =
HandlingHeaders(Header.order ? Header.order : 99);TableHeaders[HeaderOrder] = Key;
I’ve replaced the Header.order from the second demo with the variable HeaderOrder.
HandlingHeaders is a function that checks if there’s no value in the index passed in the TableHeaders array … no value in that index? cool, return that number … value in that number? add 1 and check again.
In our case, both userId and title have order 2
[ empty x 2, "userId", .....]
userId will take that spot since it comes first in our schema, when it’s time for the title to be called, HandlingHeaders will be called with the order of title (2) … oh no someone already filled that spot! recursion happens, calls HandlingHeaders(3) and this time and our array will look like this
[ empty x 2, "userId", "title", ......]
and that’s how we’ll handle having two objects in our schema with the same order.
In case we didn’t receive an order at all in our schema, I handled it with a small condition before passing the values to HandlingHeaders
const HeaderOrder =
HandlingHeaders(Header.order ? Header.order : 99);
And that’s the two edge case scenarios!
The result will look like this:
Hope you found this post useful,
Feel free to leave a comment if you have any questions.
And you can find all the code from the demos here: https://github.com/mazenadel19/React-SortingTableColumns