graphql-code-generator
graphql-code-generator copied to clipboard
Cannot read/write nested fragments
Versions
Versions
- @graphql-codegen/[email protected]
- @graphql-codegen/[email protected]
- @graphql-codegen/[email protected]
- @graphql-codegen/[email protected]
- @graphql-codegen/[email protected]
- @graphql-codegen/[email protected]
- @graphql-codegen/[email protected]
- @graphql-codegen/[email protected]
Describe the bug
In our project, we create a new GraphQL file for each query, mutation, and fragment. Out of that, a types file is generated, including the GraphQL document.
We're making use of the Apollo write/read fragment feature, in order to store some state in the Apollo cache or simply overwrite some data. For this, we use the document of the fragment from the generated types file.
With the latest update, we get an error, that no fragment was found for a specific name. We looked a bit deeper into that and found out, for fragments that import another fragment, the fragment is not included in the respective document.
fragment Zip on Zip {
zip
}
#import "./zip.fragment.gql"
fragment Address on Address {
street
zip {
...Zip
}
}
import { AddressFragmentDoc } from './address.fragment.gql-types.tsx';
client.writeFragment({
fragment: AddressFragmentDoc,
data: {
// the data
}
})
This causes the following error: Invariant Violation: No fragment named Zip.
Looking into the changes of our current upgrade PR, we can see that for all fragments that all fragment.definitions assignments to the document got removed, while they been added to the respective query and mutations.
Example:
export const AddressFragmentDoc = {
kind: 'Document',
defintions: [
{
// the current fragment document defintion
}
- ...ZipFragmentDoc.definitions
]
}
It seems, by removing the definitions of the imported fragment we lose the information about the fragment.
Questions
- is this a bug?
- is there any configuration around this issue?
@johannesbraeunig Can you please provide a reproduction or even better pr with a failing test for this?
@n1ru4l I was able to narrow it down to the option dedupeFragments. As soon as this option is enabled the imported fragment document doesn't get included in the fragment, while the import of the document of the imported fragment is still there.
Here is an example:
With dedupeFragment: false:
- Config: https://codesandbox.io/s/gql-code-generator-without-dedup-fragments-nwucx?file=/codegen.yml:333-358
- The Fragment which imports a fragment: https://codesandbox.io/s/gql-code-generator-without-dedup-fragments-nwucx?file=/src/user.fragment.graphql
- The import of the fragment document in the generated file: https://codesandbox.io/s/gql-code-generator-without-dedup-fragments-nwucx?file=/src/user.fragment.generated.tsx:186-253
- The correct assignment of the fragment document definitions https://codesandbox.io/s/gql-code-generator-without-dedup-fragments-nwucx?file=/src/user.fragment.generated.tsx:1764-1802
With dedupeFragment: true:
- Config: https://codesandbox.io/s/gql-code-generator-with-dedup-fragments-3o3jc?file=/codegen.yml:333-357
- The Fragment which imports a fragment: https://codesandbox.io/s/gql-code-generator-with-dedup-fragments-3o3jc?file=/src/user.fragment.graphql
- The import of the fragment document in the generated file: https://codesandbox.io/s/gql-code-generator-with-dedup-fragments-3o3jc?file=/src/user.fragment.generated.tsx:151-218
- The now missing document definition assignment: https://codesandbox.io/s/gql-code-generator-with-dedup-fragments-3o3jc?file=/src/user.fragment.generated.tsx:1722-1728
This is exactly what happens in our project using dedupeFragment the option: All document definition assignments got deleted, while the import is still there. The respective query using the fragment which imports a fragment does assign all fragments.
This way we cannot use fragments, to read/write data to the cache, that import fragments because they do not contain the respective document definition of the imported fragment.
I believe this changed in v2, as we got bit by this during the upgrade. Previously reading nested fragments worked fine, even with dedupeFragment enabled.
I'm hitting this as well. Is there a fix in sight?
Experiencing this as well
With dedupeFragments: false, the server complains due to the same fragment being included multiple times in the same operation. So, we have to use dedupeFragments: true. But, when we use it, the problem explained above happens. I have tried using dedupeFragments: true only in certain plugins such as typescript-operations, but that doesn't work either. I would expect the fragment definitions to be included in fragment docs, but get deduped in a smart way in operation docs.
Here is a really annoying workaround:
cache.writeFragment({
fragment: {
...FooBarFragmentDoc,
definitions: [
...FooBarFragmentDoc.definitions,
...NestedFragmentDoc.definitions,
...AnotherNestedFragmentDoc.definitions,
// ... any other fragment that's needed, add more of them as you get errors
],
},
fragmentName: 'FooBar',
data: {
// ...
}
});
fragment FooBar on FooBar {
# some fields
nested {
...Nested
}
}
fragment Nested on SomeType {
# some fields
something {
...AnotherNested
}
}
fragment AnotherNested on Something {
# some fields
}