😎 Discover cool tips and tricks for customization in our next Developer Deep Dive virtual event - sign up now!

How to show thumbnail/title from deeply nested objects in a schema

3 replies
Last updated: Feb 27, 2023
I have a schema that looks like below.
The issue is that I want to show the thumbnail/title from deeply nested objects and I'm not sure how to achieve that.
content
can be either
photo
or
video
and they have slightly different structure. But it seems like I need to use dot notation in the
select
to be able to get the reference properly, does that mean I should do something like:

select: {
  videoContent: 'content.[0].video',
  imageContent: 'content.[0].image.asset.originalFilename'
  layout: 'layout',
  bleed: 'bleed',
},
and then use
prepare
to determine if it's if type photo or video? Feels like there must be a better way.

production.js:
export default defineType({
  name: 'production',
  title: 'Productions',
  type: 'document',
  fields: [
    defineField({
      title: 'Content',
      name: 'content',
      type: 'array',
      of: [{
        type: 'productionContent',
      }]
    }),
  ],
})

productionContent.js:
export default {
  name: 'productionContent',
  title: 'Content',
  type: 'object',
  fields: [{
    name: 'content',
    title: 'Content',
    type: 'content',
  }],
  preview: {
    select: {
      content: 'content.[0]', <-- how to get either video or photo content here?
    },
    prepare(selection) {
      return {
        ...selection,
      }
    }
  }
}

content.js:
export default {
  name: 'content',
  title: 'Content',
  type: 'array',
  of: [
    {
      title: 'Photo',
      name: 'photo',
      type: 'photo',
    },
    {
      title: 'Video',
      name: 'video',
      type: 'video',
    },
  ]
}

photo.js
export default {
  name: 'photo',
  title: 'Photo',
  type: 'object',
  fields: [
    {
      title: 'Photo',
      name: 'image',
      type: 'image',
    },
  ],
  preview: {
    select: {
      media: 'image',
      title: 'image.asset.originalFilename'
    },
    prepare(selection) {
      return {
        ...selection,
        status: 'Photo'
      }
    }
  },
}

video.js
export default {
  name: 'video',
  title: 'Video',
  type: 'object',
  fields: [
    {
      title: 'Title',
      name: 'title',
      type: 'string',
    },
    {
      title: 'Video',
      name: 'video',
      type: 'mux.video',
    },
    {
      title: 'Preview Image',
      name: 'image',
      type: 'image',
    }
  ],
  preview: {
    select: {
      title: 'title',
      media: 'image'
    },
    prepare(selection) {
      return {
        ...selection,
        status: 'Video', 
      }
    }
  },
}
Feb 27, 2023, 12:16 PM
export default {
  name: 'productionContent',
  title: 'Content',
  type: 'object',
  fields: [{
    name: 'content',
    title: 'Content',
    type: 'content',
  }],
  preview: {
    select: {
      content: 'content.[0]', <-- how to get either video or photo content here?
    },
    prepare(selection) {
      return {
        ...selection,
      }
    }
  }
}
What I normally do to double check I have correct values is console.log
selection
itself.
So like:


...
prepare(selection) {
   console.log('selection', selection);
   ...
}
I would open browser console and see the if the keys I have gathered from from
select
are actually there and correct.
Feb 27, 2023, 2:16 PM
yeah, the issue seems to be that references are not actually populated unless you specifically ask for a nested value
Feb 27, 2023, 2:21 PM
yeah. I just really rely on that trick to double check what I’m getting.
Feb 27, 2023, 2:24 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.

Was this answer helpful?