Discussion on validating uniqueness of hospital names in a document, with code snippets provided.

16 replies
Last updated: Jul 27, 2021
can anyone guide me on how to validate uniqueness in a document i have tried but not working I want to validate hospital namesvalidation: Rule => Rule.required().custom((input)=>{       
          return client.fetch(
count(*[_type == "hospitalManagement" && title == "${input}"])
)          .then(count  =>  {
            if (count > 0){
              return 'Title needs to be unique'
            }else{
              return true
            }
          })
        })
Jul 22, 2021, 10:48 AM
Do you want hospital names to be unique across all documents or just those titles of the type
hospitalManagement
?
Jul 22, 2021, 3:03 PM
Across all Document
Jul 22, 2021, 3:36 PM
Across all Document
Jul 22, 2021, 3:36 PM
I got stuck at some cases its working and in some cases its not can you please guide me through this.
user A
Jul 22, 2021, 3:37 PM
I don’t know that this is the best way to approach your use case, as something like RxJS might be more appropriate, but it seems to at least satisfy the validation when I tested it a bit. Perhaps it can at least be a starting point.

import sanityClient from 'part:@sanity/base/client'

const client = sanityClient.withConfig({ apiVersion: '2021-07-22'})

export function isUniqueAcrossAllDocuments(title, options) {
  const {document} = options

  const id = document._id.replace(/^drafts\./, '')
  const params = {
    draft: `drafts.${id}`,
    published: id,
    title
  }

  const query = `!defined(*[!(_id in [$draft, $published]) && title == $title][0]._id)`

  return client.fetch(query, params)
}

export default {
  name: 'vivek',
  title: 'Vivek Unique Documents',
  type: 'document',
  fields: [
    {
      name: 'title',
      title: 'Title',
      type: 'string',
      validation: Rule => Rule.required().custom(async (doc, context) => {
        const result = await isUniqueAcrossAllDocuments(doc, context)
        return result ? true : 'Titles must be unique.'
      })
    }
  ]
}
Jul 22, 2021, 5:01 PM
Here’s what’s happening from top-to-bottom:
• We’re importing and configuring the Sanity client, which we’ll use to fetch all documents.
• We’re setting up a function that will take in two parameters: the title of the current document and an object that will give us access to the document’s
_id
.• We use some logic to check (1) if the current
_id
is defined as a draft or published document anywhere other than itself and where (2) the title is the same as the title of the current document; we then use the
!defined()
GROQ function to return true if it’s not defined (in other words, return true when the document
title
is unique).• If the title is not unique, we return a string, which the studio’s validation prints out as an error (given we used the
required()
method at the start) and prevents the user from publishing.As with all validation in the studio, this is all studio-only so there’s nothing preventing a non-unique title from being added via the API.
Jul 22, 2021, 5:12 PM
Thanks for the help
user A
will go through this approach.
Jul 23, 2021, 4:08 AM
No problem! Please let me know how it goes.
Jul 23, 2021, 4:09 AM
Yeah sure👍
Jul 23, 2021, 4:10 AM
user A
it worked Big thank you to you. I also want to appreciate your content and videos in youtube are awesome keep up the good work👍.
Jul 23, 2021, 4:22 AM
user A
it worked Big thank you to you. I also want to appreciate your content and videos in youtube are awesome keep up the good work👍.
Jul 23, 2021, 4:22 AM
Glad to hear it, Vivek!
Jul 23, 2021, 2:45 PM
Hello
user A
if i want to do validation of blank spaces at start and also of special character then?export function isUniqueAcrossAllDocuments(title, options) {
      const {document} = options
      const id = document._id.replace(/^drafts\./, '')
      const params = {
        draft: 
drafts.${id}
,        published: id,
        title
      }
      const query = 
!defined(*[!(_id in [$draft, $published]) && title == $title][0]._id)
      
      return client.fetch(query, params)
    }
    export function isValid(title){
      if(title===undefined){
        return true;
      }
      const regex = /^[a-zA-Z1-9\s]+$/;
      if (!regex.test(title)) {
        return "Invalid character"
      } 
      if(title.startsWith(" ")){
        console.log("contains space");
        return "Can't Input Blank Space at Start"
      }
    }
export default {
    name: 'hospitalManagement',
    title: 'Hospital Management',
    type: 'document',
    
    //__experimental_actions: ['create','update', 'delete','publish'],
    
    
    fields: [
      {
        name: 'title',
        title: 'Name Of Hospital',
        type: 'string',
        
        validation: Rule => Rule.required().custom(async (doc, context) => {
          console.log(context)
          var res = context.document.title;
          console.log(res);
          const result = await isUniqueAcrossAllDocuments(doc, context)
          isValid(res)
          
          return result ? true : 'Titles must be unique.'
        })
      },
Jul 27, 2021, 12:48 PM
how to integrate my function isvalid in this
Jul 27, 2021, 12:48 PM
i have created the logic for it just stuck on integrating it
Jul 27, 2021, 12:49 PM
Resolved the issue.
Jul 27, 2021, 1:08 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?