artemis icon indicating copy to clipboard operation
artemis copied to clipboard

'dart(invalid_override)' when merging a fragment of a type already used inside the query

Open SwannLV opened this issue 5 years ago • 5 comments

I have an invalid_override error in my generated file when I use fragments like in this sample:
merge fragment error.zip

Error is : 'MyQuery$Query$Country.items=' ('void Function(MyQuery$Query$Country$Items)') isn't a valid override of 'CountryMixin.items=' ('void Function(CountryMixin$Items)').dart(invalid_override)

(And no error during building)

This is pretty critical when using fragments.

Thanks a lot!

SwannLV avatar May 05 '20 12:05 SwannLV

query MyQuery {
  countries{
    id
    iso2
    items {
      id
    }
    ...Country
  }
} 

fragment Country on Country {
  id
  iso3
  items {
    count
  }
}

items does not seem to merge properly

SwannLV avatar May 05 '20 12:05 SwannLV

This one is the most important of my requests by far, my code is a mess without it 🙂 Thank you very much 🙏

SwannLV avatar May 06 '20 23:05 SwannLV

Hello @SwannLV, thank you so much for drilling this down into an easy reproducible demo.

As you could see, this happens because we purposely don't merge classes on Artemis (because we don't know how each query would evolve, avoiding breaking changes on code due to the own code generation on query changes)

There's no easy way to "fix" this issue, but it can absolutely be thrown while generating the files.

One thing you could do is to make the fragment query all possible fields, so you wouldn't have to query the field on the query.

Another way would be to use an alias on the query or on the fragment, but of course you'd need to look at those fields from two different class properties.

Of course none of these are "solutions", and I'm open to inputs about how to solve this issue.

comigor avatar May 08 '20 00:05 comigor

Hi @comigor ! Thank you very much for everything.

I took the "alias way". It works ok for my case. But I feel that I won't bother at all having breaking changes in my code if code generation happens... or maybe I am missing something.

Even more, I am expecting my code to break if I change one fragment of my query.

SwannLV avatar May 11 '20 20:05 SwannLV

Really? I gathered feedback from some people and did some tests, and the breaking change seemed pretty annoying.

For example, if we had those two queries, and they both generated the same class Person for its results:

query a {
  people(first: 10) {
    name
  }
}

query b {
  venue(byId: 1) {
    peopleNearby {
      name
    }
  }
}

But later on, I change query B to select a new field:

query b {
  venue(byId: 1) {
    peopleNearby {
      name
      age
    }
  }
}

Now query B can't use Person anymore as the selection set is different. By adding this new age field, query B would return a new Person2 class, and that would break all code that was using it as Person (eg. List<Person> people;, or other generics class).

That's my reasoning about this. I might be wrong, but it feels bad to break this way. I'm thinking about other ways to use the same class, but avoiding breaking change, but none seem straightforward.

comigor avatar May 12 '20 13:05 comigor