Handling missing values

The following query will only return attributes that exist in the matching document because no attributes have been defined in a projection.
*[_type == "event"][0]
However if you now add a projection and define an attribute which does not exist, instead of being absent from the response, it will return as null
.
*[_type == "event"][0]{ fakeAttribute}
This is null
response is expected and in many cases useful—but it can be annoying to handle in your front end.
It's good practice to use projections but now you have to expect every attribute to potentially be null
, and this requires a lot of defensive coding.
For example:
data?.headline?.name ?? 'Headliner not yet confirmed'
With a little extra GROQ you can prevent null
values and return explicit values instead.
The coalesce()
function returns the first value that is not null
.
headline
artist reference and always return a string*[_type == "event"][0...5]{ "headline": coalesce(headline->name, "Unconfirmed")}
You can use this same tactic values other than strings, you can do numbers too, or...
Similarly, the coalesce
function can be used to always return an array—even an empty array—which can be preferable to null
.
The details
Portable Text field is an array of block content.
*[_type == "event"][0...5]{ "details": coalesce(details, [])}
Now instead of checking if details
is an array and if it has blocks, you need only check its length.
Setting aside the fact that I think you should avoid using booleans at all—string literals are type safe and more flexible—if you have a boolean field you can make sure it only ever returns a boolean value.
Your current schema does not have a boolean field type. But to always return booleans, create a boolean value in the query.
For example, if you had a boolean field called isSoldOut
and queried it like this:
*[_type == "event"]{ isSoldOut}
The resulting isSoldOut
could be one of true
, false
or null
(the last of which is falsy, but still this negates the point of a boolean, right?)
You can always return a boolean by querying for it like this:
*[_type == "event"]{ "isSoldOut": isSoldOut == true}
Now isSoldOut
is only ever true
or false
.
With all that, you're much sharper on all things GROQ! Good luck completing the rest of the Mastering Content Operations track