Unlock seamless workflows and faster delivery with our latest releases - Join the deep dive

How to filter an array of references based on a field in the same document.

10 replies
Last updated: Jan 17, 2024
Hey y’all. Could someone point me to some documentation on how to filter an array of references based on field in the same document? I am working on a portfolio and want to be able to create groups of projects based on a field found in the project. For example, each project has an
Area
field that could be one of a pre-defined list of options (Visual Communication, Product Design, Environmental Design, etc). As I am building my pages, I’d like to have the ability to add choose an
Area
option prior to creating a
Project Group
so that when I go to add projects to the group, I am only given the projects with that field.Thanks in advance.
Jan 16, 2024, 9:23 PM
so in plain english you want to group posts by whether or not a post has a field set correct? so probably want the Defined GROQ function
Jan 16, 2024, 10:34 PM
not sure I understand this bit though
I’d like to have the ability to add choose an
Area
option prior to creating a
Project Group
so that when I go to add projects to the group, I am only given the projects with that field.
Jan 16, 2024, 10:37 PM
oh ok you want to filter the array reference at runtime when you make a choice?
Jan 16, 2024, 10:38 PM
Correct. Thanks for the translation.:)
Jan 16, 2024, 10:39 PM
here is the docs around filtering : https://www.sanity.io/docs/reference-type#filter-ebd7a95f9dc6
and here is a post someone replied to that has what you need I believe:
https://www.sanity.io/answers/filtering-reference-based-on-selected-product
Jan 16, 2024, 10:44 PM
you basically need to use the
document
object to find the field value you want to filter the references by.
Jan 16, 2024, 10:46 PM
Fantastic! Thanks for the help.
Jan 16, 2024, 10:46 PM
Thanks again for your help, but I can’t seem to make this work. Using the
document
as a starting point to locate the field I need seems a long way to go to get the value I need. And
parent
does get me up the level I need. How would I get to the field
designArea
with the local object?
import React from 'react';

export default {
  name: 'projectGroup',
  title: 'Project Group',
  type: 'object',
  initialValue: {
    disabled: false,
  },
  fields: [
    {
      name: 'designArea',
      title: 'Design Area',
      type: 'designArea',
    },
    {
      name: 'content',
      title: 'Projects',
      description: 'Choose from our projects.',
      type: 'array',
      of: [
        {
          type: 'reference',
          to: [{ type: 'project' }],
          options: {
            filter: ({ document }) => {
              // Get value of designArea, if any
              if (!document.designArea) {
                // If no designArea has been set…
                return {
                  filter: 'visibility == $visibility',
                  params: { visibility: true },
                };
              }
              // If designArea has been set…
              return {
                filter: 'visibility == $visibility && area == $designArea',
                params: {visibility: true, designArea: document.designArea}
              }
            },
          },
        },
      ],
      validation: (Rule) => Rule.max(12),
    },
    {
      name: 'disabled',
      title: 'Disable?',
      type: 'boolean',
    },
  ],
  preview: {
    select: {
      disabled: 'disabled',
      project0: 'projects.0.title',
      project1: 'projects.1.title',
      project2: 'projects.2.title',
      project3: 'projects.3.title',
    },
    prepare: ({ disabled, project0, project1, project2, project3 }) => {
      const projects = [project0, project1, project2].filter(Boolean);
      const subtitle = projects.length > 0 ? projects.join(', ') : '';
      const hasMoreProjects = Boolean(project3);
      return {
        title: `Project Group`,
        subtitle: hasMoreProjects ? `${subtitle}…` : subtitle,
        media: (
          <span style={{ fontSize: '1.5rem' }}>
            {disabled || disabled == null ? ':skull:' : ':white_check_mark:'}
          </span>
        ),
      };
    },
  },
};
Jan 17, 2024, 4:59 PM
Yup! Got it sorted out. Thanks for the reply though!
Jan 17, 2024, 9:56 PM
Great!
Jan 17, 2024, 9:57 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?