Filtering and removing array items based on type in Sanity.io

11 replies
Last updated: Jun 5, 2024
Hello everyone :)
I have created a section which has an array of items of multiple types.
I've used filter to only show one type of items at a time but if an item is already referenced in the array field it doesn't go away when the filter changes.
How do i de-reference/remove the items of the undesired types when the filter value is changed.


{

// Field with items

title: 'Items',

name: 'itemsArray',

type: 'array',

of: [

{

type: 'reference',

to: [{type: 'type1'}, {type: 'type2'}, {type: 'type3'}],

options: {

*filter*: ({document}: any) => {

return {
`filter:
_type == "${document.dropdown}"
,

            
}`
},

},

},

],

},
Jun 4, 2024, 2:48 PM
This is a reusable function I’ve created for this:
export const filterExistingReferences = ({
  parent,
}) => {
  const existingEntries = parent
    .map(existingEntry => existingEntry._ref)
    .filter(Boolean);
  return {
    filter: '!(_id in $existingEntries) && !(_id in path("drafts.**"))',
    params: {
      existingEntries,
    },
  };
}
Jun 4, 2024, 3:54 PM
This only filters out unique items in the selection tool. I want it to remove the referenced items if i change the filter, so if i currently have type1 as filter param and i change it to type2 i want the item that was added with type: type1 to be removed from my array entirely
Jun 4, 2024, 4:06 PM
Well, the nice thing about being an engineer is you can take examples and apply them to your own purposes. This will remove the option of adding additional items that already exist. You can extend this logic to run in a custom component to unset field.
Jun 4, 2024, 4:11 PM
Thanks, can you please link me to some examples which handle removal in a custom component, i can't find anything concrete.
Jun 4, 2024, 4:18 PM
You’ll use the
set
and
unset
method to control the value of your field in the component. There’s an example here . Don’t worry about recreating the component, just use the
renderDefault
method to use the default component.
Jun 4, 2024, 4:23 PM
Do you know of any way to get the dereferenced items from the array inside of the custom component, because i can't find a way to access the type property of the items which i need to run the filtering.
Jun 4, 2024, 5:28 PM
Ah, you’ve gotta use the
useClient
hook to set up a client that allows your to query for the references. The proper usage is:
const client = useClient({ apiVersion: '2024-06-04' })
Jun 4, 2024, 5:33 PM
You can import that hook from the
sanity
package.
Jun 4, 2024, 5:33 PM
do you know how to call unset without using onchange since i need it to activate when the dropdown value is changed not when the array is changed
Jun 4, 2024, 6:31 PM
Hokay, I’m not totally sure one that. What the
set
and
unset
functions do is generate a patch that the
onChange
function then executes. You may be able to pass the value that’s returned from
unset
to a configured client. If that’s not possible, try just unsetting the field using the client like this .
Jun 4, 2024, 6:46 PM
I ended up using a different way to do this, just by unsetting all the values of the array when the state from the dropdown is changed. But now i have another question.
When clicking on the create button, even though i have a filter that filters out the types i don't want i still have the option to create the other types that are not valid at the moment, is there a way to make the filter work for the create pop up or is there a way to remove the create button from that array.
Jun 5, 2024, 5:32 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?