Skip to content
This repository has been archived by the owner on Oct 2, 2024. It is now read-only.

Queries with fragments don't work with Artemis v7 #350

Closed
paoloposo opened this issue Aug 28, 2021 · 8 comments
Closed

Queries with fragments don't work with Artemis v7 #350

paoloposo opened this issue Aug 28, 2021 · 8 comments
Labels
bug Something isn't working

Comments

@paoloposo
Copy link

Bug description

After upgrading to version 7 in order to migrate my app to null-safety, I ran into an issue where my queries would fail. After some investigating I narrowed it down to the use of fragments in my queries.

I made a minimal working example: https://github.com/paoloposo/artemis_test

It uses the Pokemon sample API. There are two queries in the example that request the same data. One has all the fields directly in the query:

query withoutFragments {
    pokemon(name: "Blastoise") {
        id
        name
        height {
            minimum
            maximum
        }
        weight {
            minimum
            maximum
        }
        fleeRate
    }
}

The other one uses a fragment:

fragment PokemonDetails on Pokemon {
    id
    name
    height {
        minimum
        maximum
    }
    weight {
        minimum
        maximum
    }
    fleeRate
}
query withFragments {
    pokemon(name: "Blastoise") {
        ...PokemonDetails
    }
}

The first one, without the fragment, produces the expected result:

{pokemon: {id: UG9rZW1vbjowMDk=, name: Blastoise, height: {minimum: 1.4m, maximum: 1.8m}, weight: {minimum: 74.81kg, maximum: 96.19kg}, fleeRate: 0.05}}

The one with the fragment produces this, however:

{pokemon: null}

Specs

Artemis version: 7.1.1-beta.1

build.yaml:
targets:
  $default:
    sources:
      - lib/**
      - graphql/**
    builders:
      json_serializable:
        options:
          include_if_null: false
      artemis:
        options:
#          fragments_glob: graphql/fragments/*.graphql # this doesn't work either
          schema_mapping:
            - schema: graphql/schema.graphql
              queries_glob: graphql/operations/**.graphql
              output: lib/graphql/graphql_api.dart
              fragments_glob: graphql/fragments/*.graphql
Artemis output:
Precompiling executable...
Precompiled build_runner:build_runner.
[INFO] Entrypoint:Generating build script...
[INFO] Entrypoint:Generating build script completed, took 298ms

[INFO] Bootstrap:Precompiling build script......
[INFO] Bootstrap:Precompiling build script... completed, took 6.2s

[FINE] Bootstrap:Core package locations file does not exist
[WARNING] build.fallback:
The package `artemis_test` does not include some required sources in any of its targets (see their build.yaml file).
The missing sources are:
  - $package$
[INFO] BuildDefinition:Initializing inputs
[INFO] BuildDefinition:Building new asset graph...
[INFO] BuildDefinition:Building new asset graph completed, took 589ms

[INFO] BuildDefinition:Checking for unexpected pre-existing outputs....
[INFO] BuildDefinition:Checking for unexpected pre-existing outputs. completed, took 1ms

[INFO] Build:Running build...
[FINE] artemis:artemis on lib/$lib$:-> Class
[FINE] artemis:artemis on lib/$lib$:┌ [TypeName(name:r'withFragments'), TypeName(name:r'Query')][Query][null null] ()
[FINE] artemis:artemis on lib/$lib$:|   [TypeName(name:r'withFragments'), TypeName(name:r'Query')][Query][ClassName(name:r'Pokemon') ClassPropertyName(name:r'pokemon')] -> WithFragments$Query$Pokemon?
[FINE] artemis:artemis on lib/$lib$:|   -> Class
[FINE] artemis:artemis on lib/$lib$:|   ┌ [TypeName(name:r'withFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon')][Pokemon][null null] ()
[FINE] artemis:artemis on lib/$lib$:|   |   [TypeName(name:r'withFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon')]: ... expanding PokemonDetails
[FINE] artemis:artemis on lib/$lib$:|   |   |   -> Class
[FINE] artemis:artemis on lib/$lib$:|   |   |   ┌ [TypeName(name:r'withFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon'), FragmentName(name:r'PokemonDetailsMixin'), ClassName(name:r'PokemonDimension')][PokemonDimension][null null] ()
[FINE] artemis:artemis on lib/$lib$:|   |   |   |   [TypeName(name:r'withFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon'), FragmentName(name:r'PokemonDetailsMixin'), ClassName(name:r'PokemonDimension')][PokemonDimension][ClassName(name:r'String') ClassPropertyName(name:r'minimum')] -> String?
[FINE] artemis:artemis on lib/$lib$:|   |   |   |   [TypeName(name:r'withFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon'), FragmentName(name:r'PokemonDetailsMixin'), ClassName(name:r'PokemonDimension')][PokemonDimension][ClassName(name:r'String') ClassPropertyName(name:r'maximum')] -> String?
[FINE] artemis:artemis on lib/$lib$:|   |   |   └ [TypeName(name:r'withFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon'), FragmentName(name:r'PokemonDetailsMixin'), ClassName(name:r'PokemonDimension')][PokemonDimension][null null] ()
[FINE] artemis:artemis on lib/$lib$:|   |   |   <- Generated class WithFragments$Query$Pokemon$PokemonDetailsMixin$PokemonDimension.
[FINE] artemis:artemis on lib/$lib$:|   |   |   -> Class
[FINE] artemis:artemis on lib/$lib$:|   |   |   ┌ [TypeName(name:r'withFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon'), FragmentName(name:r'PokemonDetailsMixin'), ClassName(name:r'PokemonDimension')][PokemonDimension][null null] ()
[FINE] artemis:artemis on lib/$lib$:|   |   |   |   [TypeName(name:r'withFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon'), FragmentName(name:r'PokemonDetailsMixin'), ClassName(name:r'PokemonDimension')][PokemonDimension][ClassName(name:r'String') ClassPropertyName(name:r'minimum')] -> String?
[FINE] artemis:artemis on lib/$lib$:|   |   |   |   [TypeName(name:r'withFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon'), FragmentName(name:r'PokemonDetailsMixin'), ClassName(name:r'PokemonDimension')][PokemonDimension][ClassName(name:r'String') ClassPropertyName(name:r'maximum')] -> String?
[FINE] artemis:artemis on lib/$lib$:|   |   |   └ [TypeName(name:r'withFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon'), FragmentName(name:r'PokemonDetailsMixin'), ClassName(name:r'PokemonDimension')][PokemonDimension][null null] ()
[FINE] artemis:artemis on lib/$lib$:|   |   |   <- Generated class WithFragments$Query$Pokemon$PokemonDetailsMixin$PokemonDimension.
[FINE] artemis:artemis on lib/$lib$:|   └ [TypeName(name:r'withFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon')][Pokemon][null null] ()
[FINE] artemis:artemis on lib/$lib$:|   <- Generated class WithFragments$Query$Pokemon.
[FINE] artemis:artemis on lib/$lib$:└ [TypeName(name:r'withFragments'), TypeName(name:r'Query')][Query][null null] ()
[FINE] artemis:artemis on lib/$lib$:<- Generated class WithFragments$Query.
[FINE] artemis:artemis on lib/$lib$:-> Fragment
[FINE] artemis:artemis on lib/$lib$:┌ [][PokemonDetails]
[FINE] artemis:artemis on lib/$lib$:|   [FragmentName(name:r'PokemonDetails')][Pokemon][ClassName(name:r'ID') ClassPropertyName(name:r'id')] -> String
[FINE] artemis:artemis on lib/$lib$:|   [FragmentName(name:r'PokemonDetails')][Pokemon][ClassName(name:r'String') ClassPropertyName(name:r'name')] -> String?
[FINE] artemis:artemis on lib/$lib$:|   [FragmentName(name:r'PokemonDetails')][Pokemon][ClassName(name:r'PokemonDimension') ClassPropertyName(name:r'height')] -> PokemonDetailsMixin$PokemonDimension?
[FINE] artemis:artemis on lib/$lib$:|   -> Class
[FINE] artemis:artemis on lib/$lib$:|   ┌ [FragmentName(name:r'PokemonDetails'), ClassName(name:r'PokemonDimension')][PokemonDimension][null null] ()
[FINE] artemis:artemis on lib/$lib$:|   |   [FragmentName(name:r'PokemonDetails'), ClassName(name:r'PokemonDimension')][PokemonDimension][ClassName(name:r'String') ClassPropertyName(name:r'minimum')] -> String?
[FINE] artemis:artemis on lib/$lib$:|   |   [FragmentName(name:r'PokemonDetails'), ClassName(name:r'PokemonDimension')][PokemonDimension][ClassName(name:r'String') ClassPropertyName(name:r'maximum')] -> String?
[FINE] artemis:artemis on lib/$lib$:|   └ [FragmentName(name:r'PokemonDetails'), ClassName(name:r'PokemonDimension')][PokemonDimension][null null] ()
[FINE] artemis:artemis on lib/$lib$:|   <- Generated class PokemonDetailsMixin$PokemonDimension.
[FINE] artemis:artemis on lib/$lib$:|   [FragmentName(name:r'PokemonDetails')][Pokemon][ClassName(name:r'PokemonDimension') ClassPropertyName(name:r'weight')] -> PokemonDetailsMixin$PokemonDimension?
[FINE] artemis:artemis on lib/$lib$:|   -> Class
[FINE] artemis:artemis on lib/$lib$:|   ┌ [FragmentName(name:r'PokemonDetails'), ClassName(name:r'PokemonDimension')][PokemonDimension][null null] ()
[FINE] artemis:artemis on lib/$lib$:|   |   [FragmentName(name:r'PokemonDetails'), ClassName(name:r'PokemonDimension')][PokemonDimension][ClassName(name:r'String') ClassPropertyName(name:r'minimum')] -> String?
[FINE] artemis:artemis on lib/$lib$:|   |   [FragmentName(name:r'PokemonDetails'), ClassName(name:r'PokemonDimension')][PokemonDimension][ClassName(name:r'String') ClassPropertyName(name:r'maximum')] -> String?
[FINE] artemis:artemis on lib/$lib$:|   └ [FragmentName(name:r'PokemonDetails'), ClassName(name:r'PokemonDimension')][PokemonDimension][null null] ()
[FINE] artemis:artemis on lib/$lib$:|   <- Generated class PokemonDetailsMixin$PokemonDimension.
[FINE] artemis:artemis on lib/$lib$:|   [FragmentName(name:r'PokemonDetails')][Pokemon][ClassName(name:r'Float') ClassPropertyName(name:r'fleeRate')] -> double?
[FINE] artemis:artemis on lib/$lib$:└ [][PokemonDetails]
[FINE] artemis:artemis on lib/$lib$:<- Generated fragment PokemonDetailsMixin.
[FINE] artemis:artemis on lib/$lib$:-> Class
[FINE] artemis:artemis on lib/$lib$:┌ [TypeName(name:r'withoutFragments'), TypeName(name:r'Query')][Query][null null] ()
[FINE] artemis:artemis on lib/$lib$:|   [TypeName(name:r'withoutFragments'), TypeName(name:r'Query')][Query][ClassName(name:r'Pokemon') ClassPropertyName(name:r'pokemon')] -> WithoutFragments$Query$Pokemon?
[FINE] artemis:artemis on lib/$lib$:|   -> Class
[FINE] artemis:artemis on lib/$lib$:|   ┌ [TypeName(name:r'withoutFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon')][Pokemon][null null] ()
[FINE] artemis:artemis on lib/$lib$:|   |   [TypeName(name:r'withoutFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon')][Pokemon][ClassName(name:r'ID') ClassPropertyName(name:r'id')] -> String
[FINE] artemis:artemis on lib/$lib$:|   |   [TypeName(name:r'withoutFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon')][Pokemon][ClassName(name:r'String') ClassPropertyName(name:r'name')] -> String?
[FINE] artemis:artemis on lib/$lib$:|   |   [TypeName(name:r'withoutFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon')][Pokemon][ClassName(name:r'PokemonDimension') ClassPropertyName(name:r'height')] -> WithoutFragments$Query$Pokemon$PokemonDimension?
[FINE] artemis:artemis on lib/$lib$:|   |   -> Class
[FINE] artemis:artemis on lib/$lib$:|   |   ┌ [TypeName(name:r'withoutFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon'), ClassName(name:r'PokemonDimension')][PokemonDimension][null null] ()
[FINE] artemis:artemis on lib/$lib$:|   |   |   [TypeName(name:r'withoutFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon'), ClassName(name:r'PokemonDimension')][PokemonDimension][ClassName(name:r'String') ClassPropertyName(name:r'minimum')] -> String?
[FINE] artemis:artemis on lib/$lib$:|   |   |   [TypeName(name:r'withoutFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon'), ClassName(name:r'PokemonDimension')][PokemonDimension][ClassName(name:r'String') ClassPropertyName(name:r'maximum')] -> String?
[FINE] artemis:artemis on lib/$lib$:|   |   └ [TypeName(name:r'withoutFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon'), ClassName(name:r'PokemonDimension')][PokemonDimension][null null] ()
[FINE] artemis:artemis on lib/$lib$:|   |   <- Generated class WithoutFragments$Query$Pokemon$PokemonDimension.
[FINE] artemis:artemis on lib/$lib$:|   |   [TypeName(name:r'withoutFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon')][Pokemon][ClassName(name:r'PokemonDimension') ClassPropertyName(name:r'weight')] -> WithoutFragments$Query$Pokemon$PokemonDimension?
[FINE] artemis:artemis on lib/$lib$:|   |   -> Class
[FINE] artemis:artemis on lib/$lib$:|   |   ┌ [TypeName(name:r'withoutFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon'), ClassName(name:r'PokemonDimension')][PokemonDimension][null null] ()
[FINE] artemis:artemis on lib/$lib$:|   |   |   [TypeName(name:r'withoutFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon'), ClassName(name:r'PokemonDimension')][PokemonDimension][ClassName(name:r'String') ClassPropertyName(name:r'minimum')] -> String?
[FINE] artemis:artemis on lib/$lib$:|   |   |   [TypeName(name:r'withoutFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon'), ClassName(name:r'PokemonDimension')][PokemonDimension][ClassName(name:r'String') ClassPropertyName(name:r'maximum')] -> String?
[FINE] artemis:artemis on lib/$lib$:|   |   └ [TypeName(name:r'withoutFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon'), ClassName(name:r'PokemonDimension')][PokemonDimension][null null] ()
[FINE] artemis:artemis on lib/$lib$:|   |   <- Generated class WithoutFragments$Query$Pokemon$PokemonDimension.
[FINE] artemis:artemis on lib/$lib$:|   |   [TypeName(name:r'withoutFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon')][Pokemon][ClassName(name:r'Float') ClassPropertyName(name:r'fleeRate')] -> double?
[FINE] artemis:artemis on lib/$lib$:|   └ [TypeName(name:r'withoutFragments'), TypeName(name:r'Query'), ClassName(name:r'Pokemon')][Pokemon][null null] ()
[FINE] artemis:artemis on lib/$lib$:|   <- Generated class WithoutFragments$Query$Pokemon.
[FINE] artemis:artemis on lib/$lib$:└ [TypeName(name:r'withoutFragments'), TypeName(name:r'Query')][Query][null null] ()
[FINE] artemis:artemis on lib/$lib$:<- Generated class WithoutFragments$Query.
[INFO] build_resolvers:Generating SDK summary...
[INFO] Heartbeat:3.0s elapsed, 1/4 actions completed.
[INFO] build_resolvers:Generating SDK summary completed, took 2.7s

[INFO] Heartbeat:4.2s elapsed, 3/4 actions completed.
[FINE] json_serializable:json_serializable on lib/graphql/graphql_api.graphql.dart:Running JsonSerializableGenerator - 1 of 2
[FINE] json_serializable:json_serializable on lib/graphql/graphql_api.graphql.dart:Running JsonLiteralGenerator - 2 of 2
[INFO] Build:Running build completed, took 4.5s

[INFO] Build:Caching finalized dependency graph...
[INFO] Build:Caching finalized dependency graph completed, took 19ms

[INFO] Build:Succeeded after 4.5s with 4 outputs (8 actions)
@paoloposo paoloposo added the bug Something isn't working label Aug 28, 2021
@vasilich6107
Copy link
Collaborator

@paoloposo
set fetchPolicy: FetchPolicy.noCache and everything will work

image

@vasilich6107
Copy link
Collaborator

@paoloposo
it seems that you are missing store setup for cache
https://github.com/zino-app/graphql-flutter/tree/beta/packages/graphql#persistence

@vasilich6107
Copy link
Collaborator

If you look on your example the error is somewhere in cache
cause two queries are identical

the difference is the suource that graphql tries to get results

image

@samuelchanx
Copy link

@vasilich6107 May I know how to fix this issue? Using fragments in Artemis suddenly return null when used with flutter_graphql, unless I use FetchPolicy.noCache

zino-hofmann/graphql-flutter#994

@thphuccoder
Copy link

Is this fixed? I'm using ^7.8.0-beta and fragment is still not working

@vasilich6107
Copy link
Collaborator

@thphuc If you have an issue create new one with reply

@thphuccoder
Copy link

Hi @vasilich6107 thanks for your quick response. Yes, I have to use FetchPolicy.noCache to make my fragment work, like @samuelchanx mentioned

@baconcheese113
Copy link

See #393 for the solution

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants