Search code examples
reactjsapolloapollo-clientgraphql-js

useQuery to get deep local data


We using Apollo Client as our state manager.

We are succeeding to mutate a deep object but not querying that specific data connected to the id.

  • Detailed explanation below.
  • Failing query in the bottom

In this case, we are saving a nested object with template options.

const clientTemplate = {
    __typename: 'ClientTemplate',
    id: 'template',
    template: 'grid',
    displayGroups: [{
        __typename: 'ClientDisplayGroup',
        id: 'display-group-1',
        displays: [
        {
            __typename: 'ClientDisplay',
            id: 'display-1',
            label: 'Display 1',
            show: true,
            options: [
                {
                    __typename: 'ClientOption',
                    id: 'display-1-option-1',
                    value: 'normal'
                }
            ]
        }]
    }]
}

const DISPLAY_GROUP_MUTATION = gql`
    mutation TemplateClient {
        clientTemplate @client {
            id
            template
            options {
                id
                value
            }
            displayGroups {
                id
                displays {
                    id
                    show
                    options {
                        id
                        value
                    }
                }
            }
        }
    }
`

When the user changes a show option we update the data for that option.

const DISPLAY_SHOW_MUTATION = gql`
    mutation ClientDisplay {
        clientDisplay @client {
            id
            show
        }
    }
`

When running the TemplateClient and the ClientDisplay mutation the data is updated for this query.

const CLIENT_TEMPLATE = gql`
    query ClientTemplate {
        clientTemplate @client {
            id
            template
            options {
                id
                value
            }
            displayGroups {
                id
                displays {
                    id
                    show
                    options {
                        id
                        value
                    }
                }
            }
        }
    }
`

So far, all is good!

But what I’m not succeeding with is getting a specific DisplayGroup based on the id. Here is the example query.

const CLIENT_DISPLAY_GROUP = gql`
    query ClientDisplayGroup($id: ID!) {
        clientDisplayGroup(id: $id) @client {
            id
            displays {
                id
                show
                options {
                    id
                    value
                }
            }
        }
    }
`
const { data, loading, error } = useQuery(CLIENT_DISPLAY_GROUP, {
    variables: { id: 'display-group-1' }
})

The useQuery data is null so it doesn’t find any data in the cache. But ClientDisplayGroup:display-group-1 exists, and as I mentioned. The ClientTemplate returns the data!

I doubt it is possible to mutate a deep object but not query the same data. Is there anyone that can explain what we are missing here?

Thank you in advance!


Solution

  • To do this, readFragment did the trick!

    const {data}  = client.readFragment({
        id: 'ClientDisplayGroup:' + group, // The value of the to-do item's cache ID
        fragment: gql`
            fragment FragmentClientDisplayGroup on ClientDisplayGroup {
                id
                displays {
                    id
                    show
                    options {
                        id
                        value
                    }
                }
            }
        `
    })