Sorting data from a GraphQL+GraphCool Endpoint

Wes Cole
Wes Cole
Aug 26, 2017 · 4 min read

The other day, I was working on a pretty simple update to the app that I’m building on the side, Track Dat Baby, and I ran into a problem when I was trying to sort a list of data from GraphQL by date. In hindsight this was a really simple thing to do, I was just approaching it from the wrong direction.

If you aren’t familiar with what GraphQL is or what queries look like, I would recommend taking a read through the GraphQL Documentation. I’m also using GraphCool which adds some much helpful filters and query arguments that makes working with data a lot easier. I’m going to jump right into my query and my initial way of trying to handle sorting.

First, let me give you a little bit of background on the app. Track Dat Baby is a simple app for new parents to track the number of feedings and dirty diapers that their new baby has. Its a very important set of data for new parents to know because it lets them know if their baby is progressing properly in the early stages. Track Data Baby’s GraphQL schema has three different types: User, Baby, and Entry. What I was trying to do was to get a User, which has a Baby, which has Entries added to it and then sort those entries by the date in which the user added them.

Entry Type Schema:

type Entry implements Node {
baby: Baby @relation(name: "BabyOnEntry")
childType: String!
createdAt: DateTime!
id: ID! @isUnique
parentType: String!
time: DateTime! @defaultValue(value: "2017-07-30T22:51:45.384")
updatedAt: DateTime!
}

Ok, let’s work through my initial approach. Initially, I was querying for all entries associated to a baby with the following GraphQL Query.

query {
user {
id
baby {
id
entires {
id
parentType
childType
time
}
}
}
}

If you aren’t sure what that query is doing, first we request the current user, the baby associated to the user, and then the entries. We only want to get the ID, parentType, childType, and time fields in the Entry type. We are only going to be focused on the time field.

Ok, let’s get into listing out the entries and sorting them. I’m using React to build the app, so I was easily able to get the list of entries and display them using React Apollo.

import React from "react";
import { gql, graphql } from "react-apollo";
const EntriesList = props => { if (props.data.loading) {
return (
<p>{props.data.error.message}</p>
);
}

const entries = props.data.user.baby.entries;
return (
<ul>
{entries.map((entry, key) =>
<li>{entry.time}</li>
}
</ul>
);
}
export const entriesListQuery = gql`
query entries {
user {
id
baby {
id
entries {
id
parentType
childType
time
}
}
}
}
`;
const EntriesListWithData = graphql(entriesListQuery)(EntriesList);export default EntriesListWithData;

Now we have an EntriesListWithData component that will output an ul list with all of the entries listed out in the default order that they were created and with the newest being added to the bottom of the list. I would like to see the entries listed by their time field that the user sets and the newest added to the top of the list.

My first thought was “hey, Javascript has .sort maybe I should try that.” I’m sure you may already know what the problem is, but let me keep going because it stumped me and I’m sure it might stump some other people new to GraphQL. With Javascript .sort I thought that I could take the entries array and sort them before I passed them into .map like so.

{entries
.sort((a,b) => a.time - b.time )
.map(entry => <li>{time}</li> );
}

Trying to run that would would always return a specific error that I had a hard time tracking down. The code would just fail and not give me any more information about it.

TypeError: Cannot assign to read only property '1' of object '[object Array]'

I kept running through and google options trying to figure out what was going on. Finally, something clicked and I realized that GraphQL has its own sorting capabilities and that the error that I was hitting was because GraphQL’s array was read only which was causing the error to appear on the .sort.

The fix for this is very trivial. It’s a matter of making a very small change to the GraphQL query.

query entries {
user {
id
baby {
id
entries(
orderBy: time_ASC
) {
id
parentType
childType
time
}
}
}
}

If you look, you will notice that the only thing that I added was orderBy: time_ASC . What this did was order all entries by the time field and sorted them in ascending order. It was that simple. I would recommend reading through the documentation on GraphCool as this is specific to their APIs.

While I spent more time than I should have trying to figure this out, I was thrilled to find GraphCool made it so easy. Just one more reason why I am loving using GraphCool + GraphQL.

I hope this helps someone else that might be trying to learn GraphQL and needing help finding some of the small features like this.

)

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade