Discussion on setting initial values for an array field in Sanity, including suggestions for using a custom input component and reviewing the content model.

46 replies
Last updated: Jul 5, 2021
Why does sanity not support an initial value for the option list in array? If I do eg

{
      type: 'array',
      name: 'options',
      title: 'Opzioni',
      options: {
        sortable: false,
        list: [],
      },
      of: [{ type: 'string' }],
      initialValue: [{value: 'myValue', title: 'myTitle'}],
    },
the list is still empty
AI Update

I can see the confusion here! You're mixing up two different concepts in Sanity's array field configuration. The options.list property and initialValue serve completely different purposes, and your code is trying to use them incorrectly together.

What options.list actually does:

The options.list property is used with string fields (not array fields) to create a dropdown/radio/checkbox selector. When you put options.list on an array field, it doesn't do what you're expecting. Here's the correct usage for a string field with predefined options:

{
  type: 'string',
  name: 'myOption',
  title: 'My Option',
  options: {
    list: [
      {value: 'option1', title: 'Option 1'},
      {value: 'option2', title: 'Option 2'}
    ]
  }
}

What you probably want:

Based on your code, you likely want one of these scenarios:

1. Array of strings with initial values:

{
  type: 'array',
  name: 'options',
  title: 'Opzioni',
  of: [{type: 'string'}],
  initialValue: ['myValue', 'anotherValue']  // Just strings, not objects
}

2. Array of objects with value/title structure:

{
  type: 'array',
  name: 'options',
  title: 'Opzioni',
  of: [{
    type: 'object',
    fields: [
      {name: 'value', type: 'string'},
      {name: 'title', type: 'string'}
    ]
  }],
  initialValue: [
    {value: 'myValue', title: 'myTitle', _key: 'unique-key-1'}
  ]
}

Note: Array items need a _key property for tracking. Sanity usually generates these automatically, but you can provide them in initialValue.

3. String field with predefined options (most common for dropdowns):

{
  type: 'string',
  name: 'selectedOption',
  title: 'Opzione',
  options: {
    list: [
      {value: 'myValue', title: 'myTitle'},
      {value: 'otherValue', title: 'Other Title'}
    ]
  },
  initialValue: 'myValue'  // Just the value, not an object
}

The array field documentation explains that arrays are for orderable collections where you define what types can go inside using the of property. The options.list pattern simply doesn't apply to array fields - it's specifically for constraining string field values to a predefined set of choices.

I know if we pass the initial value in list array it works, but I have to perform an async call to get initial value. And list doesn’t support a function but only an array, and I don’t know how to handle this.
user A
please help me this is drive me crazy 😄
and it’s friday lol
I know if we pass the initial value in list array it works, but I have to perform an async call to get initial value. And list doesn’t support a function but only an array, and I don’t know how to handle this.
user A
please help me this is drive me crazy 😄
and it’s friday lol
I give up
yeah of couese
// @ts-ignore
import sanityClient from 'part:@sanity/base/client';
export const client = sanityClient.withConfig({ apiVersion: 'v1' });
import { kebabCase } from 'lodash';

const getHeadquarters = async () => {
  const results = await client.fetch(`(*[_type == "formMultistepBuilder"] [0] {
    "list": headquarters.headquartersOptions
 }).list`);
  return results.map((res) => {
    return {
      value: kebabCase(res.name),
      title: res.name,
    };
  });
};

export default {
  name: 'formOperator',
  type: 'object',
  title: 'Operatore',
  fields: [
    ...,
    {
      type: 'array',
      name: 'headquarters',
      title: 'Sedi',
      options: {
        list: [],
      },
      of: [{ type: 'string' }],
      initialValue: async () => {
        return await getHeadquarters();
      },
    },
  ],
};
this should be super clear
What would be a sample of something stored in
getHeadquarters
?
is on top
i can get the result as
[{value: string, title: string}]
that I can pass as initial value
but it doesn’t work
the list seems like do not accept any initial value
The result should be a list of checkbox from that function (fetched from same documents)
Hello, any update about this?
user V
I’m not entirely so sure but based on experience,
initialValue
only works on
documents
and not
object
😄
so perhaps, you could probably set it on document level
uhm
i’m not sure about that
but I will check this
thanks
user M
I’ve tried this
{
      type: 'array',
      name: 'headquarters',
      title: 'Sedi',
      options: {
        list: [],
      },
      of: [{ type: 'string' }],
      initialValue: ['test-1', 'test-2'],
    },
but it doesnt work
the inital values aren’t sets
the question is, does the list accept initial values?
Yes, it should. Bear in mind that you still need to add the list options to the
list
array for the checkboxes (and therefore the initial values) to show. Something like this should work:
{
  type: 'array',
  name: 'headquarters',
  title: 'Sedi',
  options: {
    sortable: false,
    list: [
      {value: 'test-1', title: 'Test 1'},
      {value: 'test-2', title: 'Test 2'},
    ],
  },
  of: [{ type: 'string' }],
  initialValue: ['test-1', 'test-2'],
},
ok
user M
but my problem is another,
I have to add the element in the list dynamically
but list doesn’t accept a function
what I mean is
{
      type: 'array',
      name: 'headquarters',
      title: 'Sedi',
      options: {
        list: async () => {
          return await getHeadquarters();
        },
      },
      of: [{ type: 'string' }],
    },
this doesn’t work, I need to add the element in the list based on another field of same document
I think promises are not supported there yet - only in resolving the initial values asynchronously. However, you may be able to work around it by making it a custom input component and wrapping the other field and this one in the same object or using the
withDocument
HOC to get the relevant context from the document.
Am I understanding correctly that you want to populate the list
and set the initial value based on a different field in the document? Is that field also set with an initial value or empty by default?
are empty by default
I just need to match the other fields
as checkbox elements
in this builder I’m able to add different location, then when I add operators, I can set an operator in 1 ora multiple location, based on the list that I’ve already have.
So whatever an editor enters in the other fields should become checkboxes (list options) in this field? That part you could probably accomplish using a custom input component. The initial values part is more tricky as the other fields will be empty on document creation. How would you ideally set these?
Ok, so you mean I have to create a custom component with checkboxes that I can take from sanityUI ?
Yes, I'd give that a try, although it won't solve the initial values question yet. Unfortunately, I'm not aware of any examples for this use case specifically (creating/removing check boxes based on what happens in other fields on the same doc), but please feel free to share any issues you run into.
Ok, I will try to implementi n this way
thank you!
In situations like these, it can also help to review your content model and check if there might be other ways to achieve the same that may also work, such as separate document types and references with filters. Good luck 🙂
I did it, simple and reactive to other field!
Kindly share how

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?