GROQ: query every element in an array

Viewed 31

I'm using Sanity/nextjs, and I want to query/fetch every image and their details out of an array (this is a unique slug). I've looked at the cheat sheet, and I've tried numerous methods of trying to do it, but nothing ever shows up on the page and the console isn't recording any errors.

export const getServerSideProps = async (pageContext) => {
  const setSlug = pageContext.query.slug;

  const setQuery = `*[_type == 'set' && slug.current == $setSlug][0]`;
  const imagesQuery = `*[_type == 'set']{set_images[]{image{
    asset->{_id, url}, alt, name, date, size, materials}}}`;

  const setData = await client.fetch(setQuery, {setSlug});
  const imagesData = await client.fetch(imagesQuery, {setSlug})

  return {
    props: {setData, imagesData}
  }

Calling it like: <li><img href={imagesData.image} /></li>

Here's my schema, I'm trying to get everything within the set_images.

export default {
    name: 'set',
    type: 'document',
    title: 'Set',
    fields: [
        {
            name: 'set_name',
            type: 'string',
            title: 'Set Name',
        },
        {
            name: 'slug',
            title: 'Slug',
            type: 'slug',
            options: {
                source: 'set_name'
            }
        },
        {
            name: 'set_images',
            type: 'array',
            title: 'Set Images',
            of: [
                {
                    name: 'image',
                    type: 'image',
                    title: 'Image',
                    options: {
                        hotspot: true,
                    },
                    fields: [
                        {
                            name: 'alt',
                            type: 'string',
                            title: 'Alternative Text',
                            options: {
                                isHighlighted: true
                            }
                        },
                        {
                            name: 'name',
                            type: 'string',
                            title: 'Name',
                            options: {
                                isHighlighted: true
                            }
                        },
                        {
                            name: 'date',
                            type: 'string',
                            title: 'Date',
                            options: {
                                isHighlighted: true
                            }
                        },
                        {
                            name: 'size',
                            type: 'string',
                            title: 'Size',
                            options: {
                                isHighlighted: true
                            }
                        },
                        {
                            name: 'materials',
                            type: 'string',
                            title: 'Materials',
                            options: {
                                isHighlighted: true
                            }
                        },
                    ]
                },
            ]
        }
    ]
}
2 Answers

Since you are using Sanity, you need to generate Image URL with plugin like @sanity/image-url.

npm install --save @sanity/image-url

Configure it in your sanity client.

import React from 'react'
import myConfiguredSanityClient from './sanityClient'
import imageUrlBuilder from '@sanity/image-url'

const builder = imageUrlBuilder(myConfiguredSanityClient)

function urlFor(source) {
  return builder.image(source)
}

Now just import the urlFor in your component and use for getting images.

<img src={urlFor(imagesData.image).url()} />

Correction for the post: I was calling it like src={urlFor(imagesData.image).auto('format').url()}, not <li><img href={imagesData.image} /></li> (tired brain).

Answer: I needed to change my schema so that my array was accepting an object with images in its field, not an image with fields as it returned every image as 'null'.

This reflects the change in my schema:

{...
            name: 'set_images',
            type: 'array',
            title: 'Set Images',
            of: [
                {
                    name: 'imageItem',
                    type: 'object',
                    title: 'Image Item',
                    options: {
                        hotspot: true,
                    },
                    fields: [
                        {
                            name: 'image',
                            type: 'image',
                            title: 'Image'
                        },    ...

And this is how I queried it:

const imagesQuery = `*[_type == 'set' && slug.current == $setSlug][0]{'imageItems':set_images[]{image{
    asset->{_id, url}, alt, name, date, size, materials}}}`;

And made sure it was mapping through imagesData.imageItems

Related