apollographql / apollo-tooling

✏️ Apollo CLI for client tooling (Mostly replaced by Rover)
https://apollographql.com
MIT License
3.04k stars 469 forks source link

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

Open hamxabaig opened 5 years ago

hamxabaig commented 5 years ago

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

AlexRex commented 2 years ago

Hi, is there any update on this topic?