useQuery returns data undefined when using fragments

I’m working on updating a Nextjs project that uses Apollo GraphQL (@apollo/client@npm:^3.6.6") and am trying to transition it to use fragments. I have the following query that works fine:

  query GetTeamCurrentWeek($teamId: ID!) {
    team(id: $teamId, idType: DATABASE_ID) {
      teamMeta {
        currentWeek
      }
    }
  }

If I change it to:

fragment teamCurrentWeek on RootQuery {
    team(id: $teamId, idType: DATABASE_ID) {
      teamMeta {
        currentWeek
      }
    }
  }
  query GetTeamCurrentWeek($teamId: ID!) {
    ...teamCurrentWeek
  }

useQuery returns data undefined.

If I open Apollo Devtools on the page, I can see the following query there:

fragment teamCurrentWeek on RootQuery {
  team(id: $teamId, idType: DATABASE_ID) {
    teamMeta {
      currentWeek
      __typename
    }
    __typename
  }
  __typename
}

query GetTeamCurrentWeek($teamId: ID!) {
  ...teamCurrentWeek
}

and if I run the query in the explorer, it runs and returns:

{
  "data": {
    "team": {
      "teamMeta": {
        "currentWeek": "1",
        "__typename": "TeamMeta"
      },
      "__typename": "Team"
    },
    "__typename": "RootQuery"
  }
}

It seems so strange that the query is displayed in the Apollo Devtools and runs there fine, but not from within the app.

I’m querying against Wordpress using WPGraphQL , and if I run the fragment query in the wordpress graphiql-ide, the query works fine and returns:

{
  "data": {
    "team": {
      "teamMeta": {
        "currentWeek": "1"
      }
    }
  }

So it looks like there isn’t an issue with the fragment query itself, it something about the context that the query is being executed in. However, the context seems fine, because if I revert back to the non-fragment query, everything works as expected.

I’m utterly baffled and would really appreciate any help debugging this.

Just as an aside, I should also say that debugging this has been made more difficult by the fact that Apollo Devtools in Chrome is really unstable. It appears maybe 50% of the time, sometimes disappears on a reload and only reappears when I open a fresh tab - and this is with the latest versions of Apollo Devtools (4.8.1), Apollo Client (3.6.6) and Chrome (122).

I notice that you have a uncommon “query root typename” - did you configure your cache accordingly?

As per Configuring the Apollo Client cache - Apollo GraphQL Docs, you’d need to do

const cache = new InMemoryCache({
  typePolicies: {
    RootQuery: {
      // The RootQueryFragment can only match if the cache knows the __typename
      // of the root query object.
      queryType: true,
    },
  },
});

Just as an aside, I should also say that debugging this has been made more difficult by the fact that Apollo Devtools in Chrome is really unstable.

The Apollo DevTools got a better “connection mechanism” with Apollo Client 3.8.3 - unfortunately you’ll need to update Apollo Client to benefit from that.

@lenz thank you so much for your reply. I would give you a hug if I saw you as you’ve saved me so much time!

I updated the cache options as you suggested and it’s working fine now.

So that is a consequence of the Wordpress GraphQL root query being called RootQuery? If so am I correct in thinking that anyone using the Apollo client and querying Wordpress with the stock WPGraphQL implementation needs this in their options if they’re going to use fragments?

Does this just apply to fragments on the root query or all queries? Either way, it’s definitely something that should be in the documentation/tutorials, but it’s not something I’ve ever seen mentioned before.

Also, why did it work from the Apollo Devtools and not from my application? Don’t they use the same cache?

Thanks also for your comment about Apollo Devtools. I thought I was using the latest version of the Apollo Client, but it was a typo in my package.json, so I’ve now fixed that and am running with 3.9.6, so hopefully things will be a bit easier now.

Thank you again for your help :slight_smile:

To my understanding, this happened only because you had a fragment on RootQuery, but without configuration Apollo Client assumes the root query type to be called Query.

Tbh., non-standard root entity names are very uncommon, so this probably doesn’t come up a lot. But I agree that if this is common in the Wordpress world, Wordpress-specific tutorials should probably point it out.

I’m not sure how we could point it out more prominently in the Apollo Client docs without clobbering the docs - there are probably hundreds of similar “edge case” scenarios that we call out in the docs (like I linked to above), but we cannot put all of them onto the “first page” :confused:

Actually I was thinking that it was something that the WPGraphQL developers should highlight in their documentation as they’re presumably the ones who named the root query.

I’ve been in contact with Jason Bahl at WPGraphQL perviously, so I’ll at least make sure they’re aware of it and see if they would like to update their docs.

That would be great, thank you a lot!

@lenz Quick question. Why does the Apollo Client fail silently and return undefined when the cache isn’t configured correctly for root queries? Apollo Client is otherwise really good at highlighting errors, and one of the reasons I so struggled with this was because there was no indication of what was wrong. Is there a setting I could have set to catch this, or is there a reason it just fails silently?

Because from the Client’s perspective, it’s not an error. You could have a dozen different fragments in there that are applied only conditionally.

query Foo {
  id
  ... on SomeType {
    name
  }
  ... on SomeOtherType {
    zodiac
  }
  ... on YetAnotherType {
    color
  }
}

This is a perfectly valid query, and probably only one of the fragments will match. If the server returns an unrelated type, even none of the fragments will match.

If none matches, the Client cannot distinguish between “it was intended that none match” or “one definitely should have matched, so error out”. That might be your intent as a programmer, but even if none matches, it’s a perfectly fine GraphQL query.

Ah - that makes sense now. Thanks for the clarification.