How to make a reference inside an array of arrays in Slack thread
28 replies
Last updated: Apr 25, 2022
C
How can I make a reference inside an array of arrays ?
So the end result looks like:
*[_type == 'presentation'][0]{ projects[]-> { 'presentationSlides': presentationSlides[].images, }, }
presentationSlides[].imagesin this case is an array of images. What I want is keep the array inside
presentationSlidesbut just have the url.
So the end result looks like:
{ projects: [ { presentationSlides: [ [ 'https://...', 'https://...', ], [ 'https://...', 'https://...', ], ] } ] }
Apr 22, 2022, 3:32 PM
C
I'm trying to do but it kills one level and do something like this:
presentationSlides[].images[].asset->url
{ projects: [ { presentationSlides: [ 'https://...', 'https://...', 'https://...', 'https://...', ] } ] }
Apr 22, 2022, 3:50 PM
J
So, FYI, nested arrays aren’t supported. There is a very good, basic data processing reason for this that I’m not sure I can easily state, but it’s a good reason!
The schema work arround:
• instead of
here for this.
The schema work arround:
• instead of
array[array[]]• nest an object containing arrays in the schema
array[object{array[]}]You should be able to transform the output in a groq query to something resembling what you want with some nested queries, joins, and mutations. Start
here for this.
Apr 22, 2022, 5:58 PM
J
I haven’t tried pushing this to its limits, but there may be a UI limitation to how many nested levels you can go. Here’s a schema snip of arr>obj>arr :
{ name: 'arr1', title: 'Array One Test', type: 'array', of: [ { name: 'object1', title: 'Object One Test', type: 'object', fields: [ { name: 'arr2', title: 'Array Two Test', type: 'array', of: [ {type: 'string'} ] } ] } ] },
Apr 22, 2022, 6:00 PM
J
Honestly, if you’re going deeper than this example, spreading out your content would be advised for the sake of easier management regardless. The middle-object also allows you to add multiple fields in the input modal nicely, so you can have a few different named arrays or other types per object within the top level array.
Apr 22, 2022, 6:02 PM
J
Chatting with
user A
about this on the side. In case you just meant just creating the desired output with a query:If I understand the question, this is a bit different from the ‘arrays inside arrays’ limitation. It sounds like they want to change this:
```*[_type == 'presentation'][0]{
projects[]-> {
'presentationSlides': presentationSlides[].images,
},
}```
to something like this:
```*[_type == 'presentation'][0]{
'presentationSlides': projects[]->presentationSlides[].images,
}```
I haven’t tested the above but believe it would do what they’re after.
Apr 22, 2022, 6:24 PM
C
user M
This gives me nullfor each elements in the array.
Apr 22, 2022, 7:16 PM
C
user U
Thanks for testing this out. The solution you shared give me the exact same result unfortunately.Apr 22, 2022, 7:20 PM
user D
I don't have your schema, so it won't be exactly the same. You'll need to apply this logic to your own structure.Apr 22, 2022, 7:21 PM
C
That's the issue. It seems that you have a single image in each
presentationSlide. For me I have an array of images. I don't understand at this point how to get only the url of each image in the array.
Apr 22, 2022, 7:24 PM
C
Just a few tests here: https://cln.sh/OHIsUV I don't get why if I change it to
images[].asset->urlit takes all the content and put it in the array above.
Apr 22, 2022, 7:30 PM
If you change
imageto
images[]in Racheal’s snippet, do you get what you’re after at the level you want it?
Apr 22, 2022, 7:36 PM
C
Yes that's the issue. I get a flat array with 3 objects inside instead of having 2 objects (first one having 2 objects and second one having 1 object).
Apr 22, 2022, 7:39 PM
Ahh, like this then?
*[_type == 'presentation'][0]{ projects[]->{ presentationSlides[]{ 'presentationSlides': images[].asset->url } } }
Apr 22, 2022, 7:42 PM
C
Ah that's closer but now it give me an object
(by the way thanks a LOT for helping me crack this one)
presentationSlidesin each object in the array.
(by the way thanks a LOT for helping me crack this one)
Apr 22, 2022, 7:44 PM
C
Does it have to be an object in each element of the array? Can't it be an array of arrays ? If not this solution is something I could work with.
Apr 22, 2022, 7:46 PM
C
If not this solution is something I could work with.
Apr 22, 2022, 7:47 PM
I don't think there's any way of getting around having a named field for your array of urls if you want them in separate objects, like in Geoff's query.
Apr 22, 2022, 9:38 PM
presentationSlides. This might not be performant and I don’t have your schema to confirm, but going from the video you posted you might try something like:
Edit: I just replicated how I think you have your schema, and this doesn’t look like it’ll work.
*[_type == 'presentation'][0]{ ..., 'cover': cover.asset->url, 'slug': slug.current, 'projects': projects[]->presentationSlides[]{ 'title': ^.title, 'slug': ^.slug.current, 'client': ^.projects[]->client->{ title, 'slug': slug.current, }, 'presentationSlides': images[].asset->url } }
Apr 22, 2022, 10:07 PM
That said, the more I look at it, the more I think my colleagues who work on GROQ would cringe.
Apr 22, 2022, 10:08 PM
C
Oh. I surely don't want to make anyone cry about it. The last solution you shared
So the array of images is part of the array of slide. And this slide is part of an array in the project. If you want I could share my entire schema.
user A
is mixing my data not the right way. I'm setting a list of presentationSlides in each projects. And in each slide I have an array of images.So the array of images is part of the array of slide. And this slide is part of an array in the project. If you want I could share my entire schema.
Apr 23, 2022, 6:21 AM
C
export default { title: "Projects", name: "project", type: "document", initialValue: { theme: "light", priority: "medium", }, groups: [ { title: "Project Description", name: "projectDescription", }, { title: "Case Study", name: "caseStudy", }, { title: "Presentation", name: "presentation", }, ], fields: [ { title: "Cover", name: "cover", type: "image", group: "projectDescription", }, { title: "Project Title", name: "title", type: "string", group: "projectDescription", }, { title: "Project Slug", name: "slug", type: "slug", options: { source: "title", }, group: "projectDescription", }, { title: "Client", name: "client", type: "reference", to: [{ type: "client" }], group: "projectDescription", }, { title: "Theme", name: "theme", type: "string", options: { list: [ { title: "Light", value: "light" }, { title: "Dark", value: "dark" }, ], }, group: "projectDescription", }, { title: "Priority", name: "priority", type: "string", options: { list: [ { title: "High", value: "high" }, { title: "Medium", value: "medium" }, { title: "Low", value: "low" }, ], }, group: "projectDescription", }, { title: "Tags", name: "tags", type: "array", of: [ { type: "reference", to: [{ type: "tag" }], }, ], group: "projectDescription", }, { title: "Blocks", name: "blocks", type: "array", group: "caseStudy", of: [ { title: "Text Block", name: "textBlock", type: "document", initialValue: { title: "Text block", }, fields: [ { title: "Title", name: "title", type: "string" }, { name: "text", title: "Text", type: "array", of: [{ type: "block" }], }, { title: "Start", name: "start", type: "number", }, { title: "Width", name: "width", type: "number", }, ], }, { title: "Gallery", name: "gallery", type: "document", initialValue: { title: "Gallery", }, fields: [ { title: "Title", name: "title", type: "string" }, { title: "Images", name: "images", type: "array", of: [{ type: "image" }], }, ], }, ], }, { title: "Presentation Slides", name: "presentationSlides", type: "array", group: "presentation", of: [ { title: "Slide", name: "slide", type: "document", initialValue: { title: "Slide", }, fields: [ { title: "Title (Not visible on the website)", name: "title", type: "string", }, { name: "images", title: "Images", type: "array", of: [{ type: "image" }], }, ], }, ], }, ], };
Apr 23, 2022, 6:21 AM
C
export default { title: "Presentations", name: "presentation", type: "document", fields: [ { title: "Title", name: "title", type: "string", }, { title: "Slug", name: "slug", type: "slug", options: { source: "title", }, }, { title: "Cover", name: "cover", type: "image", }, { title: "Intro", name: "intro", type: "text", }, { title: "Projects", name: "projects", type: "array", of: [ { type: "reference", to: [{ type: "project" }], }, ], }, ], };
Apr 23, 2022, 6:21 AM
A
Hi all! Your challenge here is that
You should be able to use this workaround. It’s not pretty, but I think it should work for you:
This “escapes” the flattening by doing the image-to-URL mapping inside an object, and then unwrapping it.
[]is a flattening operator, so any kind of expression like
array[].nestedArray[]will cause the inner array to be flattened out.
You should be able to use this workaround. It’s not pretty, but I think it should work for you:
*[_type == 'presentation'][0]{ projects[]-> { 'presentationSlides': presentationSlides[] { 'urls': images[]->url }.urls }, }
Apr 25, 2022, 10:27 AM
C
Ah that's exactly what I was looking for. Thanks a lot
user L
. You forgot .assetso just for reference this is what worked:
*[_type == 'presentation'][0]{ projects[]-> { 'presentationSlides': presentationSlides[] { 'urls': images[].asset->url }.urls }, }
Apr 25, 2022, 10:54 AM
A
Ah, of course, sorry. 👍
Apr 25, 2022, 10:59 AM
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.