1

I am using Relay and Graphql and I have a hard time figuring out how to fetch more fields on one object in a connection.

Suppose we have the following query to populate a list of a viewer's tasks:

viewer {
  id
  tasks(first:10) {
    edges {
      node {
        id
        name
      }
    }
  }
}

When the user then selects one in the list, I want to fetch more fields on the selected one.

Here are my thoughts:

  1. I implement a new field/method on the viewer object that is called "task" and that takes an id as input and returns just the one task. Like this answer: https://stackoverflow.com/a/40712653/5820184
  2. Use the node root query to fetch the missing data. (I am not sure how to do this in relay. Do I make the root container dependent on on both queries?)
  3. Make the connection take an input of id and then only return that one task.

Now 1. seems to go against the whole "graph" model thinking by adding a "function" to fetching one element to the graph.

For number 2, I am not quite sure that using the node root query is a good practice, since it seems to be an internal relay thing?

I don't know if number 3 is a viable solution since it is kind of filtering the list which may have an impact on the list view?

UPDATE

We ended up making a field for each connection that takes an id as input an returns one element from the list. This was inspired by the way Graphcool, GitHub and others do it in their endpoints. Thanks for pointing me in the right direction.

Danny Larsen
  • 150
  • 9

2 Answers2

0

Your second approach is actually mentioned in the official Relay docs.

In your case, you could make an additional query for the specific task like this:

query SpecificNode {
  node(id: "task-id") {
    id
    ... on Task {
      name
      # more fields
    }
  }
}

The Relay API of Graphcool includes additional top-level queries to fetch one node of a specific model. A query for your case would look like this:

query SpecificTask {
  Task(id: "task-id") {
    id
    name
    # more fields
  }
}
marktani
  • 7,578
  • 6
  • 37
  • 60
  • 1
    Looks like the link is dead and the relevant info has been moved to [relay-api/one-node](https://www.graph.cool/docs/reference/relay-api/one-node-ga4chied8m) – armand Mar 24 '17 at 09:49
0

You can do that with the help of @include directive. Relay will take care of everything!

Assuming you have designed task as a separate React component, the exported Relay container will look like this:

export default Relay.createContainer(Task, {
  initialVariables: {
    taskSelected: false,
  },
  fragments: {
    viewer: () => Relay.QL`
      fragment on Viewer {
        id
        tasks(first:10) {
          edges {
            node {
              id
              name
              additionalInfo @include(if: $taskSelected) {
                where,
                when,
                who,
                priority
              }
            }
          }
        }
      }
    `,
  },
});

Fetching of additionalInfo is made conditional by using @include(if: $taskSelected), where taskSelected is a Relay variable and initialized under initialVariables property. When a viewer selects a task for more info, set taskSelected to true with:

this.props.relay.setVariables({ taskSelected: true });
Ahmad Ferdous
  • 3,351
  • 16
  • 33