ApolloError: Fragment was used, but not defined

Issue

I have this in my complicated app:

import { gql } from '@apollo/client';

gql`
  fragment StuffTable on Stuff {
    id
    status
  }
`;

export const GetStuffDocument = gql`
  query GetStuff($id: ID!) {
    stuff(id: $id) {
      id
      ...StuffTable
    }
  }
`

// Then in another file:
import { ApolloClient, useApolloClient } from '@apollo/client';
import GetStuffDocument from './OtherFile';

async function exportStuff(client: ApolloClient<unknown>): Promise<void> {
  const { data: metadata } = await client.query<GetStuffQuery>({
    query: GetStuffDocument,
  });
  // other stuff, but it fails at the client.query step.
}

function MyComponent() {
  const client = useApolloClient();
  
  return <button onClick={() => exportStuff(client)}>Download</button>
}

Basically, I have an export button which will export a CSV of my GraphQL data. I manually call client.query to fetch the latest data on click of the button, but it throws an error saying it can’t find the used fragment StuffTable. How do I include that fragment in the query?

I am getting this error:

Uncaught (in promise) Error: Fragment StuffTable was used, but not defined
    at new ApolloError (index.ts:54:1)
    at QueryManager.ts:1043:1
    at both (asyncMap.ts:30:1)
    at asyncMap.ts:19:1
    at new Promise (<anonymous>)
    at Object.then (asyncMap.ts:19:1)
    at Object.next (asyncMap.ts:31:1)
    at notifySubscription (module.js:132:1)
    at onNotify (module.js:176:1)
    at SubscriptionObserver.next (module.js:225:1)

How do I include the Fragment in my manual client.query or whatever I need to do to resolve this error and get it to work?

Is there something like this I can do?

const StuffTableFragment = gql`
  fragment StuffTable on Stuff {
    id
    status
  }
`;

// then...
const { data: metadata } = await client.query<GetStuffQuery>({
  query: GetStuffDocument,
  fragments: [StuffTableFragment],
});

I’m looking at the docs but don’t see anything of help.

Solution

You’ll need to import the fragment into your query code. Instead of this:

gql`
  fragment StuffTable on Stuff {
    id
    status
  }
`;

export const GetStuffDocument = gql`
  query GetStuff($id: ID!) {
    stuff(id: $id) {
      id
      ...StuffTable
    }
  }

You can do this:

const STUFF_TABLE_FRAGMENT = gql`
  fragment StuffTable on Stuff {
    id
    status
  }
`;

export const GetStuffDocument = gql`
  ${STUFF_TABLE_FRAGMENT}
  query GetStuff($id: ID!) {
    stuff(id: $id) {
      id
      ...StuffTable
    }
  }

That will make sure that the fragment StuffTable is included in your query!

Answered By – wuz

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published