-
Notifications
You must be signed in to change notification settings - Fork 16
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
fix: fixed conditional selection bug (empty base schema) #75
base: main
Are you sure you want to change the base?
Conversation
Please review, @gksander. Sorry for ping, but couldn't request a review, since I am no maintainer. |
|
||
invariant(data); | ||
expect(data[0]).toEqual({ name: "Bulbasaur", attack: 49 }); | ||
expect(data[1]).toEqual({}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is the thing that is getting me hung up. If there's an empty base selection, and our type looks something like ({ name: "Charmander", ... } | { name: "Bulbasaur", ... })[]
, then having an empty object is a "wrong" according to our type.
But in groq, I believe you can have an empty projection and it'll just return an empty object. So for example, this query:
*[_type == 'pokemon'][0..3]{...select(name == 'Charmander' => { name, "hp": base.HP }, name == 'Bulbasaur' => { name, "attack": base.Attack })}
does indeed pass the tests you have here, including the empty-object one – since that projection will just select nothing on everything but Charmander and Bulbasaur.
Still trying to wrap my head around this, but I think limiting our types on this might end up causing a mismatch with how groq behaves – which would be confusing.
Any thoughts on this? It's not yet clear to me how to proceed on this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Jep, that's true. Also don't know, how to proceed either. Then, I think, the PR can be closed, and it's up to the user, to check, whether the empty object is matching, or not.
Though, on the other side, if there is an empty object in the response, I don't think there is a big case for any user to show an empty tile/card/list-item/whatever, so my opinion on this would be to just add a third argument to the conditionals, and just set a default option.
I am thinking of an option named includeEmptyObject
, which is then conditionally giving the user at least the type. But then, we would need to filter the empty object on our side.
So we're working on an idea with a new To omit the empty object (or null depending on which context you use it), you pass it a default case. So here it would look like: const { data, query } = await runPokemonQuery(
q("*")
.filter("_type == 'pokemon'")
.slice(0, 3)
.select(
{
"name == 'Charmander'": {
name: q.literal("Charmander"),
hp: ["base.HP", q.number()],
},
default: {
name: q.string(),
attack: ["base.Attack", q.number()],
},
}
)
); or if you wanted specifically Bulbasaur & Charmander, you could add it to the filter, ie: const { data, query } = await runPokemonQuery(
q("*")
.filter("_type == 'pokemon' && (name == 'Charmander' || name == 'Bulbasaur')")
.select(
{
"name == 'Charmander'": {
name: q.literal("Charmander"),
hp: ["base.HP", q.number()],
},
default: {
name: q.literal("Bulbasaur"),
attack: ["base.Attack", q.number()],
},
}
)
); |
In the |
fixes #25
also touches #68