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
Jul 2, 2021, 3:24 PM
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.
Jul 2, 2021, 3:28 PM
user A
please help me this is drive me crazy 😄
Jul 2, 2021, 3:31 PM
and it’s friday lol
Jul 2, 2021, 3:31 PM
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.
Jul 2, 2021, 3:28 PM
user A
please help me this is drive me crazy 😄
Jul 2, 2021, 3:31 PM
and it’s friday lol
Jul 2, 2021, 3:31 PM
I give up
Jul 2, 2021, 3:54 PM
yeah of couese
Jul 2, 2021, 3:56 PM
// @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();
      },
    },
  ],
};
Jul 2, 2021, 3:56 PM
this should be super clear
Jul 2, 2021, 3:57 PM
What would be a sample of something stored in
getHeadquarters
?
Jul 2, 2021, 3:58 PM
is on top
Jul 2, 2021, 3:58 PM
i can get the result as
[{value: string, title: string}]
that I can pass as initial value
Jul 2, 2021, 3:59 PM
but it doesn’t work
Jul 2, 2021, 3:59 PM
the list seems like do not accept any initial value
Jul 2, 2021, 3:59 PM
The result should be a list of checkbox from that function (fetched from same documents)
Jul 2, 2021, 4:03 PM
Hello, any update about this?
Jul 5, 2021, 8:01 AM
user V
I’m not entirely so sure but based on experience,
initialValue
only works on
documents
and not
object
😄
Jul 5, 2021, 8:06 AM
so perhaps, you could probably set it on document level
Jul 5, 2021, 8:06 AM
uhm
Jul 5, 2021, 8:07 AM
i’m not sure about that
Jul 5, 2021, 8:07 AM
but I will check this
Jul 5, 2021, 8:07 AM
thanks
Jul 5, 2021, 8:07 AM
user M
I’ve tried this
{
      type: 'array',
      name: 'headquarters',
      title: 'Sedi',
      options: {
        list: [],
      },
      of: [{ type: 'string' }],
      initialValue: ['test-1', 'test-2'],
    },
Jul 5, 2021, 8:12 AM
but it doesnt work
Jul 5, 2021, 8:12 AM
the inital values aren’t sets
Jul 5, 2021, 8:12 AM
the question is, does the list accept initial values?
Jul 5, 2021, 8:14 AM
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'],
},
Jul 5, 2021, 8:18 AM
ok
user M
but my problem is another,
Jul 5, 2021, 8:18 AM
I have to add the element in the list dynamically
Jul 5, 2021, 8:18 AM
but list doesn’t accept a function
Jul 5, 2021, 8:18 AM
what I mean is
{
      type: 'array',
      name: 'headquarters',
      title: 'Sedi',
      options: {
        list: async () => {
          return await getHeadquarters();
        },
      },
      of: [{ type: 'string' }],
    },
Jul 5, 2021, 8:19 AM
this doesn’t work, I need to add the element in the list based on another field of same document
Jul 5, 2021, 8:19 AM
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?
Jul 5, 2021, 8:26 AM
are empty by default
Jul 5, 2021, 8:27 AM
I just need to match the other fields
Jul 5, 2021, 8:27 AM
as checkbox elements
Jul 5, 2021, 8:27 AM
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.
Jul 5, 2021, 8:29 AM
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?
Jul 5, 2021, 8:33 AM
Ok, so you mean I have to create a custom component with checkboxes that I can take from sanityUI ?
Jul 5, 2021, 8:34 AM
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.
Jul 5, 2021, 8:38 AM
Ok, I will try to implementi n this way
Jul 5, 2021, 8:39 AM
thank you!
Jul 5, 2021, 8:39 AM
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 🙂
Jul 5, 2021, 8:41 AM
I did it, simple and reactive to other field!
Jul 5, 2021, 8:58 AM
Kindly share how
Jul 5, 2021, 9:00 AM

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?