-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generation of Duplicated Fragments in nested fragments #3063
Comments
I am suffering from the same problem and did not find a good solution yet. It seems to make no difference if I use graphql-tag.macro or graphql-tag. |
@zerocity seems to be a bug in graphql-tag. I added a pullrequest there apollographql/graphql-tag#278 |
Is there any workaround? This is completely blocking me |
Yes there is. Ive created a minimal graphql-tag version which outputs only the source of the query instead of the full documentNode. This version did not have this bug, works with graphqlgen and is available here https://gist.github.com/lanwin/bdc33d0bf291851bda48d17f98b98ff2 I did not expect the bug fixed in graphql-tag soon. It did not seems to be active at the moment. |
@lanwin are you by any chance using a custom I'm communicating with multiple independent schemas, and wanted to use the eslint-graphql-plugin (which also supports changing the Anyway, great work on this (it's sad that it won't get merged anytime soon), but thanks for sharing. |
@sarink no I still use gql as tag name and import from "./graphql-tag-source" instead. And then Ive configured use config option to let the generator use "gqlImport: generated/graphql/graphql-tag-source" instead. |
I was encountering this error:
@mattleff and I wrote this function and are using it in our fetch wrapper to fix the issue: import { parse } from 'graphql';
import { print } from 'graphql/language/printer';
const removeDuplicateFragments = (query: string): string => {
const ast = parse(query);
const seen: string[] = [];
const newDefinitions = ast.definitions.filter((def) => {
if (def.kind !== 'FragmentDefinition') {
return true;
}
const id = `${def.name.value}-${def.typeCondition.name.value}`;
const haveSeen = seen.includes(id);
seen.push(id);
return !haveSeen;
});
const newAst = {
...ast,
definitions: newDefinitions,
};
return print(newAst);
}; |
Thank you @narthur! Here is the same thing but for Apollo Client Links: import { ApolloLink } from "@apollo/client";
/**
* Problem: Sometimes Apollo Client includes the one fragment multiple times.
* Workaround: Remove duplicate fragments from query definitions
* @see https://github.com/dotansimha/graphql-code-generator/issues/3063#issuecomment-842536997
*/
export function makeFragmentDeDupeLink() {
const fragmentDeDupeLink = new ApolloLink((operation, forward) => {
const previousDefinitions = new Set<string>();
const definitions = operation.query.definitions.filter((def) => {
if (def.kind !== "FragmentDefinition") return true;
const name = `${def.name.value}-${def.typeCondition.name.value}`;
if (previousDefinitions.has(name)) {
return false;
}
previousDefinitions.add(name);
return true;
});
const newQuery = {
...operation.query,
definitions,
};
operation.query = newQuery;
return forward(operation);
});
return fragmentDeDupeLink;
} |
I was able to resolve this issue by enabling the
|
This solution works for me, but the standard |
Thanks for this! Worked for me with named fragments 🙌🕺 |
dedupeFragments didn't seem to work with me, but this is an expanded version of the above function, in context with the httplink provided. Took me a bit to get that part put together, thought I'd leave it here for helpfulness. YMMV! import { createHttpLink } from "@apollo/client";
import { parse } from "graphql";
import { print } from "graphql/language/printer";
/**
* This will remove duplicate fragments from the request body.
* [originally written by @narthur](https://github.com/dotansimha/graphql-code-generator/issues/3063#issuecomment-771179054)
* @param fullReqStr The request body.
* @returns The request body with duplicate fragments removed.
*/
const removeDuplicateFragments = (fullReqStr: string): string => {
try {
const fullReqObject = JSON.parse(fullReqStr);
const ast = parse(fullReqObject.query);
const seen: string[] = [];
const newDefinitions = ast.definitions.filter((def: any) => {
if (def.kind !== "FragmentDefinition") {
return true;
}
const id = `${def.name.value}-${def.typeCondition.name.value}`;
const haveSeen = seen.includes(id);
seen.push(id);
return !haveSeen;
});
const newAst = {
...ast,
definitions: newDefinitions,
};
return JSON.stringify({
...fullReqObject,
query: print(newAst),
});
} catch (err: any) {
console.log("err", err);
}
// If we somehow failed at our task, just return the original string.
return fullReqStr;
};
export const createHTTPApolloLink = (uri: string) => {
return createHttpLink({
uri,
fetch: async (uri, options) => {
const fixedOptions = {
...options,
body: options?.body ? removeDuplicateFragments(options?.body as string) : undefined
};
return fetch(uri, fixedOptions);
},
});
}; |
Hi , i get several errors of "There can be only one fragment named ..." on the Client Side(Apollo).
On this example below it would be "There can be only one fragment named uptimeMeasurements"
Problem
The Group will import "PublicUptimeMeasurementsFragmentDoc" and the Component which could be a child of the group.
The generated Fragments look like this
i am using version of 1.9.1
is there a option to import fragments on queryDocument level ?
thanks for help
The text was updated successfully, but these errors were encountered: