custom input component not storing selected value

21 Views Asked by At

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.

0

There are 0 best solutions below