ferry icon indicating copy to clipboard operation
ferry copied to clipboard

Cannot use `tristate_optionals: true` in mutations having lists in their parameters

Open KevinDespoulainsTR opened this issue 1 year ago • 5 comments

Hi!

I found an issue when using the tristate_optionals: true option in ferry_generator|graphql_builder.

I forked the project and updated the pokemon_explorer example to show you how to easily reproduce the issue.

What I have done :

  • Added the gql_tristate_value: ^1.0.0 package into pubspec.yaml
  • Updated the schema.graphql file with this mutation :
type Mutation {
    ...
    updatePokemons(pokemons: [PokemonUpdateInput!]): bool!
}

input PokemonUpdateInput {
  id: Int!
  name: String!
}
  • Created a update_pokemon.graphql file under the src/graphql/ folder containing the following code :
mutation UpdatePokemons($pokemons: [PokemonUpdateInput!]) {
 updatePokemons(pokemons: $pokemons)
}

Here, if you run the dart run build_runner build --delete-conflicting-outputs, everything is working as expected 👌

Now, if you add the tristate_optionals: true to the build.yaml file :

targets:
  $default:
    builders:
      ferry_generator|graphql_builder:
        enabled: true
        options:
          schema: pokemon_explorer|lib/schema.graphql
          tristate_optionals: true
          when_extensions:
            when: true
            maybeWhen: true
      ferry_generator|serializer_builder:
        enabled: true
        options:
          schema: pokemon_explorer|lib/schema.graphql
 

And run the dart run build_runner build --delete-conflicting-outputs command, the serializes.gql.g.dart file is missing the following builder factory :

...
..addBuilderFactory(
          const FullType(
              BuiltList, const [const FullType(GPokemonUpdateInput)]),
          () => new ListBuilder<GPokemonUpdateInput>())
...

Therefore, when the code is running and the GPokemonUpdateInput needs to be serialized, there is an exception indicating that no serializer is found for the BuiltList<GPokemonUpdateInput>.

StateError (Bad state: No builder factory for BuiltList<GPokemonUpdateInput>. Fix by adding one, see SerializersBuilder.addBuilderFactory.)

If you turn off the tristate_optionals, the builder factory is added as expected and the code is running perfectly (but the tristate feature cannot be used).

Is there anything missing to be able to use tristate_optionals with mutations having lists in their parameters?

Thank you for your help and don't hesitate if you need more details!

KevinDespoulainsTR avatar Jan 23 '24 14:01 KevinDespoulainsTR

Thanks!

Most likely related to https://github.com/gql-dart/gql/issues/436 and https://github.com/google/built_value.dart/issues/124

knaeckeKami avatar Jan 23 '24 16:01 knaeckeKami

Ok, I see, thank you for the links!

Do you have a workaround for it? (Excluding adding addBuilderFactory to the serializers.gql.g.dart file because if someone else runs the build_runner command it will erase it)

KevinDespoulainsTR avatar Jan 23 '24 16:01 KevinDespoulainsTR

unfortunately, no workaround at this time.

(other than forking gql_code_builder and adding the builder factories here https://github.com/gql-dart/gql/blob/master/codegen/gql_code_builder/lib/serializer.dart#L54 )

knaeckeKami avatar Jan 23 '24 17:01 knaeckeKami

Actually, I think a workaround would be to add a Workaround type to the graphql schema which has the list in the non-nullable form.

type Workaround {
  field: [PokemonUpdateInput!]!
}

This would add the builder factory.

knaeckeKami avatar Jan 26 '24 12:01 knaeckeKami

Actually, I think a workaround would be to add a Workaround type to the graphql schema which has the list in the non-nullable form.

type Workaround {
  field: [PokemonUpdateInput!]!
}

This would add the builder factory.

This is a nice idea, thank you for your help!

KevinDespoulainsTR avatar Jan 26 '24 14:01 KevinDespoulainsTR