Skip to content
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

Fragments not working with interfaces #610

Open
letsar opened this issue Sep 2, 2024 · 8 comments
Open

Fragments not working with interfaces #610

letsar opened this issue Sep 2, 2024 · 8 comments
Assignees

Comments

@letsar
Copy link

letsar commented Sep 2, 2024

When I create a Fragment with a type which is an interface, or has fields which are interfaces, the generated code does not work at runtime.

For example let's have this schema:

interface Book {
  title: String!
  author: String!
}

type Textbook implements Book {
  title: String!
  author: String!
  courses: [String!]!
}

type ColoringBook implements Book {
  title: String!
  author: String!
  colors: [String!]!
}

type Query {
  books: [Book!]!
}

And this query:

fragment BookFragment on Book {
  title
  ... on Textbook {
      courses
  }
  ... on ColoringBook {
      colors
  }
}

query GetBooks {
  books {
    ...BookFragment
  }
}

These parameters are set on build.yaml:

  when_extensions:
    when: true
    maybeWhen: true

When we generate the code, we can see that nothing implements GBookFragment__asTextbook, yet we have this kind of generted code:

extension GBookFragmentWhenExtension on GBookFragment {
  _T when<_T>({
    required _T Function(GBookFragment__asTextbook) textbook,
    required _T Function(GBookFragment__asColoringBook) coloringBook,
    required _T Function() orElse,
  }) {
    switch (G__typename) {
      case 'Textbook':
        return textbook((this as GBookFragment__asTextbook));
      case 'ColoringBook':
        return coloringBook((this as GBookFragment__asColoringBook));
      default:
        return orElse();
    }
  }
}

Since nothing implements GBookFragment__asTextbook, the cast (this as GBookFragment__asTextbook) will fail.
Is there a workaround for that?

@knaeckeKami knaeckeKami self-assigned this Sep 2, 2024
@knaeckeKami
Copy link
Collaborator

knaeckeKami commented Sep 2, 2024

There's actually a deeper bug, the subtype-specific data does not even end up in the models

 final response = GGetBooksData.fromJson({
      "books": [
        {
          "__typename": "Textbook",
          "title": "Textbook",
          "courses": ["Math", "Science"]
        },
        {
          "__typename": "ColoringBook",
          "title": "ColoringBook",
          "colors": ["Red", "Blue"]
        }
      ]
    });
final GBookFragment textbook = response!.books[0]; // is of type _$GGetBooksData_books, with no data from the type conditions 

@letsar
Copy link
Author

letsar commented Sep 20, 2024

@knaeckeKami have you an idea on how we can fix this issue? Is it an issue from ferry or from another package?

@knaeckeKami
Copy link
Collaborator

knaeckeKami commented Sep 20, 2024

It's an issue in the code generation in gql_code_builder. I didn't have time to look into this bug specifically yet. It might be an issue in the mergeSelections() or buildInlineFragmentClasses() function.

@knaeckeKami
Copy link
Collaborator

FWIW this seems to only happen when fragments are nested. So as a workaround you could try to flatten the query.

@btrautmann
Copy link

@nhannah Pretty sure this is the issue you were talking about 👀

@letsar
Copy link
Author

letsar commented Nov 8, 2024

Hi, I had some time to look into the issue. I don't know what is really causing the issue, but I came up with what should like the data.gql.dart file :
In the class GGetBooksData, instead of BuiltList<GGetBooksData_books> get books we should have BuiltList<GBookFragmentData> get books.
The class GGetBooksData_books does not seem to be useful in this case.
Now I need to see how to change this 😅

@knaeckeKami
Copy link
Collaborator

Cool!
I also looked a bit into it already.

I think there is something what with the mergeSelections function that doesn't handle nested fragments with type conditions properly

@nhannah
Copy link

nhannah commented Jan 9, 2025

@bestdan this is the issue we are seeing today

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants