apollographql / apollographql/apollo-tooling

Apollo client:codegen doesn't work with dynamic interpolated fragment name

Open
#1,375 1 comment 17 reactions 0 assignees View on GitHub
🤖 component - codegen
Dominant language
TypeScript
Stars
3k
Forks
460
PR merge metrics
No merged PRs in 30d

Description

**Intended outcome:**

```
FieldItem.fragments = {
field: {
name: 'FieldItemFieldsFragment',
fragment: gql`
fragment FieldItemFieldsFragment on Field {
_id
name
}
`,
},
};

const QUERY = gql`
query FarmerDetailsQuery($id: ID!) {
fields(page: {offset: 0, limit: 10}, filter: {created_by: $id}) {
edges {
...${FieldItem.fragments.field.name} <---- This should work and generate types
}
}
}
${FieldItem.fragments.field.fragment}
`
```

**Actual outcome:**

Doesn't generate the typescript types for the above graphql query tag. It actually doesn't throw any error.

image

If i hardcode the fragment name there `...FieldItemFieldsFragment` it does generate the types.

**How to reproduce the issue:**

Any gql query tag where fragment name is dynamically added via string interpolation `...${fragmentName}` it'll not generate the types.

**Versions**

Apollo CLI: `apollo/2.13.1 darwin-x64 node-v8.11.2`
Command: `apollo client:codegen --globalTypesFile=config/types/graphql.types.ts --useReadOnlyTypes --target=typescript --watch --queries=src/**/*.{ts,tsx}`

**More Explanation:**

I'm trying to generate typescript types in a ReactJS project. I'm developing using the concept of "Fragment driven Components" where each dumb/UI/stateless component would define what data it requires to render and the parent component will then just include the child component's fragment to know what kind of data to fetch.

But the problem is if i type the fragment name on parent (hardcoded), it generates the types.

```
//ChildComponent.tsx
...
FieldItem.fragments = {
field: {
name: 'FieldItemFieldsFragment',
fragment: gql`
fragment FieldItemFieldsFragment on Field {
_id
name
}
`,
},
};

// ParentComponent.tsx
const QUERY = gql`
query FarmerDetailsQuery($id: ID!) {
fields(page: {offset: 0, limit: 10}, filter: {created_by: $id}) {
edges {
...FieldItemFieldsFragment <---- This works like this
}
}
}
${FieldItem.fragments.field.fragment}
`
```

But if i try to dynamically include the fragment name using `interpolation` it doesn't generate the types

```
//ChildComponent.tsx
...
FieldItem.fragments = {
field: {
name: 'FieldItemFieldsFragment',
fragment: gql`
fragment FieldItemFieldsFragment on Field {
_id
name
}
`,
},
};

// ParentComponent.tsx
const QUERY = gql`
query FarmerDetailsQuery($id: ID!) {
fields(page: {offset: 0, limit: 10}, filter: {created_by: $id}) {
edges {
...${FieldItem.fragments.field.name} <---- This doesnt work using interpolation
}
}
}
${FieldItem.fragments.field.fragment}
`
```

and actually if i `console.log` the query, `gql` actually generates the correct javascript object with this `...${FieldItem.fragments.field.name} `

![image](https://user-images.githubusercontent.com/12872177/60601716-fe302200-9dcb-11e9-8c36-6dd37dfa6c26.png)

Contributor guide

Open the contributing guide

Research direction

Reproduce the issue with the Apollo client:codegen command and the shown gql query using an interpolated fragment name. Trace how the codegen entry point handles interpolated fragments, then verify that the query generates TypeScript types as it does when the fragment name is hardcoded.

Written by the indexing model from the issue text.

Assessment

Tech stack
graphql, react, typescript
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.