sanity

Filter in sanity


To add language to the schema and do localization, I'm using documentInternationalization from '@sanity/document-internationalization'. Where I utilized another schema in my parent schema, I wanted to filter, but I couldn't find out how.

defineField({  name: 'product',
  type: 'array',
  of: [{type: 'reference', to: [{type: 'dogTreat'}, {type: 'catTreat'}]}],
  options: {
    filter: ({ document }) => {
    let currentLanguage = document.language; 
    return {
      filter: `_type == "catTreat" && slug.current == '${currentLanguage}' `,
      params: {
        type:'catTreat'},
      }
    }
  },
  group: 'products',
}),

If the current page is in en-US, I would want to see the en-US version of the product in the dropdown menu. I have provided language to both schemas, but I'm unable to filter it. Could anyone possibly assist?


Solution

  • It looks to be a problem with your filter.A few things to note:

    1. Options are in the wrong place | Currently your options are being applied to the array. They should be nested inside your reference type, otherwise it has no function.

    2. Multiple _type restrictions | In general, I would only recommend filtering the type in one location. In your array reference, you're allowing the user to select both dogTreat, and catTreat. In your filter, you're then restricting that specifically to catTreat. I would remove the _type from the filter and only do this in the reference type if possible.

    3. Incorrectly passing params to the filter | You're correctly fetching the document's language with let currentLanguage = document.language, but you're then incorrectly passing that to the filter. You shouldn't use string interpolation to pass variables, but rather the params object (like you've used for the 'type' property. The way you reference that variables then also changes to something like this: return {filter: 'slug.current == $language', params: {language: currentLanguage}}.

    4. Filtering the wrong value | I've also just set up reference filtering depending on the document language, and you do this by then filtering the language property of the document, not slug.current.

    Your field should look something like this:

          defineField({
          title: 'Products',
          name: 'product',
          type: 'array',
          of: [
            defineArrayMember({
              type: 'reference',
              to: { type: 'catTreat' },
              options: {
                filter: ({ document }) => {
                  const { language } = document
        
                  if (language) {
                    return {
                      filter: 'language == $language',
                      params: {
                        language: language,
                      },
                    }
                  }
        
                  return {}
                },
              },
            }),
          ],
          group: 'products',
        })