apollo icon indicating copy to clipboard operation
apollo copied to clipboard

IntrospectionFragmentMatcher doesn't work

Open aleandro-coppola opened this issue 5 years ago • 3 comments

I am trying to use InMemoryCache but I always get this error:

_You are using the simple (heuristic) fragment matcher, but your queries contain union or interface types. Apollo Client will not be able to accurately map fragments. To make this error go away, use the IntrospectionFragmentMatcher as described in the docs: https://www.apollographql.com/docs/react/advanced/fragments.html#fragment-matcher

WARNING: heuristic fragment matching going on!_

for this query:

 node(id: $id) {
      ... on Order {
         discountApplications(first: 10) {
          edges {
            node {
              value {
               
                  ... on MoneyV2 {
                  amount
                 }
                ... on PricingPercentageValue {
                  percentage
                }

              }
            }
          }
        }
     }
}

My configurations:

nuxt-config.js

clientConfigs: {
      default: '~/plugins/apollo-config.js',
      .... 
}

apollo-config.js

const { InMemoryCache } = require('@apollo/client');
import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';

import schema from '../schema.json';
const fragmentMatcher = new IntrospectionFragmentMatcher({
  introspectionQueryResultData: schema,
});
const cache = new InMemoryCache({
  fragmentMatcher,
});

export default (context) => {
  return {
    // required
    httpEndpoint: 'endpoint',
    // optional
    // override HTTP endpoint in browser only
    // browserHttpEndpoint: '/graphql',
    // optional
    // See https://www.apollographql.com/docs/link/links/http.html#options
    httpLinkOptions: {
      // credentials: 'same-origin'
      headers: {
        'Content-Type': 'application/json',
        'X-Shopify-Storefront-Access-Token': '[token]',
      },
    },
    // You can use `wss` for secure connection (recommended in production)
    // Use `null` to disable subscriptions
    // wsEndpoint: 'ws://localhost:4000', // optional
    // LocalStorage token
    tokenName: 'client', // optional
    // Enable Automatic Query persisting with Apollo Engine
    persisting: false, // Optional
    // Use websockets for everything (no HTTP)
    // You need to pass a `wsEndpoint` for this to work
    websocketsOnly: false, // Optional
    cache,
  };
};

schemaQuery.js

const fetch = require('cross-fetch');
const fs = require('fs');

fetch(`[endpoint]`, {
  method: 'POST',
  headers: {
    Accept: 'application/json',
    'Content-Type': 'application/json',
    'X-Shopify-Storefront-Access-Token': '[token]',
  },
  body: JSON.stringify({
    variables: {},
    query: `
      {
        __schema {
          types {
            kind
            name
            possibleTypes {
              name
            }
          }
        }
      }
    `,
  }),
})
  .then((result) => result.json())
  .then((result) => {
    // here we're filtering out any type information unrelated to unions or interfaces
    const filteredData = result.data.__schema.types.filter((type) => type.possibleTypes !== null);
    result.data.__schema.types = filteredData;
    fs.writeFileSync('./schema.json', JSON.stringify(result.data), (err) => {
      if (err) {
        console.error('Error writing fragmentTypes file', err);
      } else {
        console.log('Fragment types successfully extracted!');
      }
    });
  });

Once this is done, the queries all work but I always have this problem

aleandro-coppola avatar Dec 22 '20 16:12 aleandro-coppola

I am facing a similar issue at the moment. This is how I have configured the apollo client:

const GRAPHQL_URL = '########################';
import possibleTypes from '~/possibleTypes.json'

import {
    IntrospectionFragmentMatcher,
    InMemoryCache,
  } from "apollo-cache-inmemory";

const fragmentMatcher = new IntrospectionFragmentMatcher({ possibleTypes });

export default (context) => {
    return {
        httpEndpoint: GRAPHQL_URL,
        credentials: 'include',
        cache: new InMemoryCache({fragmentMatcher}),
        httpLinkOptions: {
            credentials: 'include',
            headers: {
                "brand": "default"
          }
        }
    }
  }

And I am getting the following error

Network error: Error writing result to store for query:
....
FragmentMatcher.match() was called before FragmentMatcher.init()

iddogino avatar Dec 26 '20 19:12 iddogino

Same issue here. Is this the only solution for it: https://medium.com/commutatus/whats-going-on-with-the-heuristic-fragment-matcher-in-graphql-apollo-client-e721075e92be?

Is it possible to fix this in the core package?

memic84 avatar Jan 19 '21 20:01 memic84

@Coppola-Aleandro I found this difficult myself, but finally found a solution. See my response to this question here https://stackoverflow.com/a/66066033/9067927

toddpadwick avatar Feb 22 '21 16:02 toddpadwick