Reputation: 2167
I have long enum like that:
enum Vegetable {
TOMATO
POTATO
ONION
# ...and many more
}
and type
type VegetableInfo {
isRed: Boolean!
bbb: Int!
ccc: String!
}
Now I want to provide frontend all vegetables info.
I could just return array of vegetables:
type Query {
vegetables: [Vegetable]!
}
But since it will be indexed array and not associative, in frontend JS I will be NOT able to quickly access data for needed vegetable like so:
vegetables.tomato.isRed // true
// or maybe
vegetables.TOMATO.isRed // true
Instead I will be forced to write some search function to check if tomato exists in any item. I need associative array (object with keys) instead.
I can easy achieve this by doing this:
type Query {
vegetables: VegetablesInfo!
}
enum Vegetable {
TOMATO
POTATO
ONION
# ...and many more
}
type VegetablesInfo {
TOMATO: VegetableInfo!
POTATO: VegetableInfo!
ONION: VegetableInfo!
# ...and many more
}
type VegetableInfo {
isRed: Boolean!
bbb: Int!
ccc: String!
}
But enum is not even used here. I still need that enum in other parts of graphql. I will have to repeat every vgetable name in both places, so it's bad.
I cannot find any way to generate type keys from enum. Code below will not work, but is there something like this?
type VegetablesInfo {
...Vegetable: VegetableInfo!
}
Upvotes: 1
Views: 605
Reputation: 25659
GraphQL spec: The target field of a field selection must be defined on the scoped type of the selection set.
In plain English, no, you can't "dynamically" define fields. Types can only have explicitly defined fields. As you say, the practical solution is to return a list of VegetableInfo
(adding a name: Vegetable
field) to the client. The client can trivially filter the list for the target Vegetable
by name:
// client.ts
const vegFinder = (name: Vegetable, vegetables: VegetableInfo[]): VegetableInfo | undefined => {
return vegetables.find((veg) => veg.name === name)
}
Upvotes: 2