In a Sanity Studio v3 project I have a product collection schema...
export default defineType({
name: 'collection',
title: 'Collection',
type: 'document',
icon: PackageIcon,
groups: GROUPS,
fields: [
// more fields
// Rules
defineField({
name: 'rules',
title: 'Rules',
type: 'array',
group: 'rules',
description: 'Include products that satisfy these conditions',
of: [
{
type: 'collectionRule',
},
],
}),
})
and the collectionRule schema:
export default defineField({
title: 'Collection rule',
name: 'collectionRule',
type: 'object',
icon: FilterIcon,
fields: [
// Column
defineField({
title: 'Relation',
name: 'relation',
type: 'string',
initialValue: 'Tag',
readOnly: true,
}),
// Condition
defineField({
title: 'Condition',
name: 'condition',
type: 'string',
options: {
list: ['contains', 'equals'],
},
}),
// Values
defineField({
title: 'Select a tag',
name: 'selectedTag',
type: 'string',
initialValue: '',
components: {
input: TagSelector,
},
}),
],
})
in my sanity.config.ts:
defineConfig({
// other stuff
form: {
...,
inputResolver: (type, schema) => {
if (type.name === 'selectedTag' && schema.name === 'printify.collectionRule') {
return TagSelector
}
return undefined
},
},
}
})
and the component:
import React, {useEffect, useState} from 'react'
import {createClient} from '@sanity/client'
import {Select} from '@sanity/ui'
const client = createClient({
projectId: {never-you-mind-:)},
dataset: 'production',
apiVersion: process.env.SANITY_STUDIO_API_VERSION,
token: process.env.SANITY_STUDIO_ADMIN_TOKEN,
useCdn: false,
})
export const TagSelector = ({type, value, onChange}) => {
const [tags, setTags] = useState([])
useEffect(() => {
const fetchTags = async () => {
const query = `*[_type=='product']{
'tags':store.tags
}`
const results = await client.fetch(query)
const allTags = results.flatMap((product) => product.tags.split(', '))
const uniqueTags = [...new Set(allTags)]
uniqueTags.sort((a, b) => a.localeCompare(b))
setTags(uniqueTags)
}
fetchTags()
}, [])
const handleChange = (event) => {
console.log('Selected tag:', event.target.value) // returns "Selected tag: Regular fit"
// const path = ['selectedTag'] // Replace 'fieldName' with the actual field name
// Create the patch object
const patch = {
set: {
selectedTag: event.target.value, // Use the path array here
},
}
// if (!Array.isArray(patch.path)) {
// throw new Error('Patch path must be an array')
// }
console.log('Patch object:', JSON.stringify(patch)) // returns "Patch object: {"set":{"selectedTag":"Regular fit"}}"
onChange(patch)
}
return (
<Select onChange={handleChange} value={value}>
{tags.map((tag) => (
<option key={tag} value={tag}>
{tag}
</option>
))}
</Select>
)
}
All the code checks out but I keep getting an error "TypeError: patch2.path is not iterable", the selectedTag Select is correctly populated and I can select a tag. But my selectedTag does not retain the value
I've been circling the drain with this for too long now. Any help would be greatly appreciated.