Maintaining an ordered list in graphql/relay

1.6k views Asked by At

I want to show a list of tasks in a specific order. The problem is, that the user should be able to change the order and have that saved to graphql (The user can also add and delete tasks from the lists). Currently we have implemented the list as a relay connection and add/delete/update are working fine. Here are what we are considering now:

  • Make graphql return an ordered list. Then copy that list to local state in the component and reorder the list there. Then just notify graphql about the changes.
  • Make graphql return a number on all tasks that is the sort order.
  • Make graphql return a linked list. So every tasks has a reference to the next in the list.

As I see it, there are some issues with each of these. With the ordered list and copying it to local state we have to handle add/remove actions somehow and update the local state accordingly.

With the number sorting order, if we use running numbers, e.g. 1..2..3.., we have to update many numbers when we want to move number 200 in between number 1 and 2. This seems like a lot of updates, and I am not sure how this is handled in relay/graphql.

With the linked list there is also a lot of bookkeeping involved in changing the order and I am not sure how this is handled in relay mutations. Perhaps returning 3 tasks from the mutation (all the tasks that have changed the pointer to the next in the list) and specify that in the "FIELDS_CHANGE" config?

Which is the best solution when using relay/graphql/react? Other solutions are very welcome.

1

There are 1 answers

0
Fge On

We went down the path to create a separate mutation for moving an item in relation to another one:

  • The general get query returns an ordered list without any order key or such
  • Moving an item is done by either a moveBefore or moveAfter mutation, returning the newly sorted list. Arguments are new itemToMove and relativeTarget.

The signature for the mutation roughly looks like this:

moveAfter(itemToMove: ID!, itemToMoveAfter: ID!): Item[]

Moving an item before another item has the same signature & behavior, just the server side logic is a bit different.

As we're not using relay, I cannot comment on how to make relay aware of the changes though.