Structured Content 2022: Join our conference to explore fresh perspectives on content and digital experiences β†’

Is there a way to resolve a reference in a custom validation?

10 replies
Last updated: Oct 14, 2020

Is there a way to resolve a reference in a custom validation?I have an array that can hold two different types of references. I would like to validate that it holds at least on of each type.

Thank you in advanced
πŸ™

{
  name: 'tags',
  title: 'Tags',
  type: 'array',
  of: [
    {
      type: 'reference',
      to: [{ type: 'artist' }, { type: 'category' }],
    },
  ],
  validation: (Rule) =>
    Rule.required().custom((data) => {
      /*
        That is what i get from the data item. 
        But I need to know the type of the reference (artist or category)
        
        data [{…}]
          0:
          _key: "b29ee1dbb22a"
          _ref: "96e38ca0-b075-4777-b8f4-d2d6ca123df0"
          _type: "reference"
      */

    }),
},

Sep 8, 2020, 9:49 AM

Sorry this was lost in the flow here... here's a suggestion:

import { uniq } from 'lodash'

...

      validation: Rule => Rule.custom(data => {
        const types = data.map(item => item._type)
        const uniqTypes = uniq(types)
        return uniqTypes.length > 1
          ? true
          : 'Must have at least one of each'
      }),

Sep 20, 2020, 9:34 AM

ah.. right you need the reference...

Sep 20, 2020, 9:36 AM

Yes! Thanks for getting back. I am referring to two different document types

[{ type: 'artist' }, { type: 'category' }]
. I want to validate that at least one of each category is in the array. But in the validation, i can not resolve toe reference. Is this even possible?

Sep 20, 2020, 9:38 AM

Something along these lines... (untested)

import { uniq } from 'lodash'
import client from 'part:@sanity/base/client'

...

      validation: Rule => Rule.custom(data => {
        const referencedIds = data.map(item => item._ref)
        return client.fetch(`*[_id in $ids]._type`, {
          ids: referencedIds
        })
        .then(res => {
          const uniqTypes = uniq(res)
          return uniqTypes.length > 1
            ? true
            : 'Must have at least one of each'  
        })
      }),

Sep 20, 2020, 9:42 AM

Nice! Does the client work out of the box, or do i need to add the credential somewhere?

Sep 20, 2020, 9:43 AM

It's preconfigured

Sep 20, 2020, 9:43 AM

Thanks a lot!

Sep 20, 2020, 9:43 AM

You might have to tweak it, it's just from the top of my head πŸ˜„

Sep 20, 2020, 9:44 AM

Sure, but knowing that i can use the client in the schema definitions opens a whole new universe for me 😎

Sep 20, 2020, 9:45 AM

joined the slack channel to find a solution to this same problem, very happy to have found it

Oct 14, 2020, 7:53 PM

Sanity.io: Get the most out of your content

Sanity.io is a platform to build websites and applications. It comes with great APIs that let you treat content like data. Give your team exactly what they need to edit and publish their content with the customizable Sanity Studio. Get real-time collaboration out of the box. Sanity.io comes with a hosted datastore for JSON documents, query languages like GROQ and GraphQL, CDNs, on-demand asset transformations, presentation agnostic rich text, plugins, and much more.

Don't compromise on developer experience. Join thousands of developers and trusted companies and power your content with Sanity.io. Free to get started, pay-as-you-go on all plans.