How to use GROQ to Write Loops
10 replies
Last updated: Jun 29, 2021
A
I'm trying to use GROQ to save me writing some loops in the front end.
I have an array of tasks, in this array there is a property named "usedTime" indicating how long has been spent on a task, only some of the tasks have this value.
The result I'm after is one array (one dimentional) containing the usedTime data, I can handle null values in my front end but if sanity supports omitting them that would be awesome
Attached is the result of the query
I know my naming work needs improving
😉
I've tried several methods
All my attempts return "null"
Any idea on how I can achive this?
🙂
I have an array of tasks, in this array there is a property named "usedTime" indicating how long has been spent on a task, only some of the tasks have this value.
The result I'm after is one array (one dimentional) containing the usedTime data, I can handle null values in my front end but if sanity supports omitting them that would be awesome
Attached is the result of the query
*[_type == "internalCustomers" && '<mailto:myMail@mail.com|myMail@mail.com>' in users[]->email]{ "totalHours": tasks[].tasks[], }
😉
I've tried several methods
"totalHours": tasks[].tasks->usedTime, "totalHours": tasks[].tasks[]->usedTime, "totalHours": tasks[].tasks[]->.usedTime, "totalHours": tasks[].tasks.usedTime,
Any idea on how I can achive this?
🙂
Jun 29, 2021, 4:33 PM
G
I’m wondering if there might be another array to include in your query, given the double-nesting after
Schema:
GROQ query:
Returns:
totalHoursin your third array item.
Schema:
export default { name: 'andreas', type: 'document', fields: [ { name: 'tasks', type: 'array', of: [ { name: 'firstObj', type: 'object', fields: [ { name: 'tasks', type: 'array', of: [ { name: 'secondObj', type: 'object', fields: [ { name: 'tasks', type: 'array', of: [ { name: 'thirdObj', type: 'object', fields: [ { name: 'usedTime', type: 'number' }, ], }, ], }, ], }, ] } ] } ] } ] }
*[_type == 'andreas'] { 'totalHours': tasks[].tasks[].tasks[].usedTime }
"result": [ 0: { "totalHours": [ 0: 34 ] } ]
Jun 29, 2021, 7:06 PM
G
As for removing null values, I believe you could try
[count(totalHours) > 0]at the end of your query. In my example above, it came after the
}at the end of the projection.
*[_type == 'andreas'] { 'totalHours': tasks[].tasks[].tasks[].usedTime }[count(totalHours) > 0]
Jun 29, 2021, 7:09 PM
A
Hey Geoff, yes it seems to be another arrayed hidden in here. Can't really see why
Your suggestion makes sense, but does not work. I can't see a name for the additional array either
Results of
is null
If I remove the last task-attribute I get this response
https://ad47v47a.api.sanity.io/v1/data/query/production?query=*%5B_type%20%3D%3D%20%22in[…]%20%20%27totalHours%27%3A%20tasks%5B%5D.tasks%5B%5D%0A%7D
Your suggestion makes sense, but does not work. I can't see a name for the additional array either
Results of
*[_type == "internalCustomers" && '<mailto:andreas.jacobsen@inklud.no|andreas.jacobsen@inklud.no>' in users[]->email]{ 'totalHours': tasks[].tasks[].tasks[] }
If I remove the last task-attribute I get this response
https://ad47v47a.api.sanity.io/v1/data/query/production?query=*%5B_type%20%3D%3D%20%22in[…]%20%20%27totalHours%27%3A%20tasks%5B%5D.tasks%5B%5D%0A%7D
Jun 29, 2021, 7:22 PM
A
Hey Geoff, yes it seems to be another arrayed hidden in here. Can't really see why
Your suggestion makes sense, but does not work. I can't see a name for the additional array either
Results of
is null
If I remove the last task-attribute I get this response
https://ad47v47a.api.sanity.io/v1/data/query/production?query=*%5B_type%20%3D%3D%20%22in[…]%20%20%27totalHours%27%3A%20tasks%5B%5D.tasks%5B%5D%0A%7D
Your suggestion makes sense, but does not work. I can't see a name for the additional array either
Results of
*[_type == "internalCustomers" && '<mailto:andreas.jacobsen@inklud.no|andreas.jacobsen@inklud.no>' in users[]->email]{ 'totalHours': tasks[].tasks[].tasks[] }
If I remove the last task-attribute I get this response
https://ad47v47a.api.sanity.io/v1/data/query/production?query=*%5B_type%20%3D%3D%20%22in[…]%20%20%27totalHours%27%3A%20tasks%5B%5D.tasks%5B%5D%0A%7D
Jun 29, 2021, 7:22 PM
A
Thanks, using v2021-03-25 in my front end, will change to that in studio as well. Same problem with v2021-03-25
Edit: Sorry my mistake, using the newer API I get the result I want
🙂
Edit: Sorry my mistake, using the newer API I get the result I want
🙂
Jun 29, 2021, 7:45 PM
Also, this might be the thing you want?
*[_type == "internalCustomers" && '<mailto:andreas.jacobsen@inklud.no|andreas.jacobsen@inklud.no>' in users[]->email]{ 'totalHours': tasks[tasks != null].tasks }
Jun 29, 2021, 7:49 PM
A
GROQ is amazingI tried your not null example Knut, but weirdly I get one null value
But this is pretty easy to handle in the front end
But this is pretty easy to handle in the front end
Jun 29, 2021, 7:54 PM
Try
*[_type == "internalCustomers" && '<mailto:andreas.jacobsen@inklud.no|andreas.jacobsen@inklud.no>' in users[]->email]{ 'totalHours': tasks[tasks != null].tasks[usedTime != null].usedTime }[count(totalHours) > 0]
Jun 29, 2021, 7:57 PM
A
thanks! That worked, I'll remove count because I just remember that count and sum is not the same thing. GROQ just saved me a bunch of loops I'd have to maintain and try to understand again some time in the future 🙂 Should have thought of tasks being able to be null as well
Jun 29, 2021, 8:00 PM
Sanity– build remarkable experiences at scale
Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.