πŸ‘€ Our most exciting product launch yet πŸš€ Join us May 8th for Sanity Connect

Trouble with previewing custom object in portable text block, resolved with help from community member

11 replies
Last updated: Sep 28, 2021
Hi, I'm having trouble figuring out how to properly preview a custom object in a portable text block. Here is the custom block that I insert into the portable text object:

// objects/metric.js
import {IoTrendingUpOutline} from 'react-icons/io5'

export default {
  title: 'Metric',
  name: 'metric',
  type: 'object',
  icon: IoTrendingUpOutline,
  fields: [
    {
      title: 'Label',
      name: 'label',
      type: 'string'
    },
    {
      title: 'Key Number',
      name: 'keyNumber',
      type: 'string'
    },
    {
      title: 'Metric Type',
      name: 'metricType',
      type: 'string',
      options: {
        list: [
          {title: 'Number', value: 'number'},
          {title: 'Increase', value: 'increase'},
          {title: 'Decrease', value: 'Decrease'}
        ]
      }
    }
  ],
  preview: {
    select: {
      label: 'metric.label',
      keyNumber: 'metric.keyNumber',
      metricType: 'metric.metricType'
    },
    prepare (data) {
      let subtitlePrepend = ''
      switch (data.metricType) {
        case 'increase':
          subtitlePrepend = 'Increase in'
          break
        case 'decrease':
          subtitlePrepend = 'Decrease in'
          break
        default:
          subtitlePrepend = ''
          break
      }
      return {
        ...data,
        title: data.keyNumber,
        subtitle: subtitlePrepend && data.label.join(' ')
      }
    }
  }
}
is my switch or the use of
prepare (data)
messing it up in some way? Should I try and move the switch logic into a
previewComponent
(like is shown in this videoEmbedPreview example )?
Sep 28, 2021, 12:17 AM
Using what you wrote
user M
its an improvement... but not quite there:the Subtitle still isn't rendering
Sep 28, 2021, 12:38 AM
Disregard my last response. It works perfectly, I missed something when copying & 🍝 πŸ€¦β€β™‚οΈ TYSM!!! πŸ™ πŸ™Œ
Sep 28, 2021, 12:40 AM
βœ…
Sep 28, 2021, 12:40 AM
So, only problem with your solution compared to the switch case method, is i'd like to not show anything in the beginning if Number is selected (as you can see in the attached screenshot). Maybe we can do this with a ternary statement?
Sep 28, 2021, 12:46 AM
This is what I'm trying so far:
...
  preview: {
    select: {
      title: 'keyNumber',
      label: 'label',
      metricType: 'metricType'
    },
    prepare ({title, label, metricType}) {
      return {
        title,
        subtitle: (metricType[0] !== 'number' ? `${metricType.charAt(0).toUpperCase() + metricType.slice(1)} in ` : ``) + label
      }
    }
  }
...
Sep 28, 2021, 12:55 AM
but, I think theres something wrong with the
metricType[0]
, because its still giving me the Number in Survey Respondents
Sep 28, 2021, 12:55 AM
but, I think theres something wrong with the selection, because its still giving me the Number in Survey Respondents
Sep 28, 2021, 12:55 AM
try:
subtitle: `${metricType != 'number' ? `${metricType.charAt(0).toUpperCase() + metricType.slice(1)} in ` : '' }${label}`
Sep 28, 2021, 12:56 AM
works perfectly! (searches for chef's kiss emoji) πŸ‘©β€πŸ³
thanks again you're my MVP of the day
user M
Sep 28, 2021, 12:59 AM
Someone could argue that a ternary is less readable than a good old
if
or
switch
statement, but if that happens feel free to blame me!
Sep 28, 2021, 1:02 AM
haha important thing is it's working and takes up less space ✨
Sep 28, 2021, 1:07 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.

Was this answer helpful?