Join us live Sept. 27 – How Sanity and Vercel powered Morning Brew's transformation –>
September 22, 2021

Conditional fields in Array of type Object - Sanity.io

By Dorell James

Working with hiding fields in an object schema when you use it in an array can get tricky (or at least for me). It wasn't really obvious to me at first! If you're in the same situation just like me and looking for solutions, I hope this guide is helpful and will save you some time!

ICYMI. Sanity.io released conditional fields and yay, it basically allows us to hide a given field depending on the values available to us in our document. Cool, neat, awesome, you name it but I’d say finally! Yes!!!

Let’s take a look at an example below at how we can conditionally hide a field of an object in the a given list of array:

// organization document schema
{
  name: "organization",
  title: "Organization",
  type: "document",
  fields: [
    ...,
    {
      title: "Members",
      description: "Manage users of a given org here...",
      name: "members",
      type: "array",
      of: [{ type: "organizationMember" }],
    }
  ]
}

So we have here an organization document above with members belonging to that organization via organizationMember object schema.

Now, our organizationMember as specified below:

// organizationMember object schema
{
  name: "organizationMember",
  title: "Organization Member",
  type: "object",
  fields: [
    ...,
    {
      name: "status",
      title: "Status",
      type: "string",
      options: {
        list: [
          { title: "Invited", value: "invited" },
          { title: "Accepted", value: "accepted" },
        ],
      },
      defaultValue: "invited",
    },
    {
      name: "dateInvited",
      title: "Date Invited",
      type: "datetime",
    },
    {
      name: "dateAccepted",
      title: "Date Accepted",
      type: "datetime",
    },
  ]
}

Notice we have dateAccepted field above. Our goal is we only want that given field to show only when the status has changed to accepted.

So what’s the problem?

The solution might come pretty simple but getting the object of whatever we’re currently viewing or editing becomes tricky (or maybe not or at least for me 😅).

We’ll ask ourselves, how are we gonna make sure we’re selecting the appropriate object at a given time? Or how do I get hold of the current index of the object? If you’ve come across this problem, read on the solution below.

The Solution

The first thing we need to do is to get hold of the current organizationMember object we’re currently working. Correct? Whether that’s the first index, or 2nd or whatever, we must grab it.

So, we’ll have to make use of entire document value and the current value from the callback properties provided by Sanity.io for us and from there, we can look at our members array in our document and find the current field’s value that matches.

{
  name: "dateAccepted",
  title: "Date Accepted",
  type: "datetime",
  hidden: ({ document, value }) => {
    // Grabs the current object we're editing based on
    // the current value of the field
    const member = document.members.find(
      (member) => member.dateAccepted === value
    );
    console.log(member)
  },
}

So now, we’ve got access to the appropriate object and the output of console.log(member) statement as for example is:

// member 1
{
  "_key": "6cb0dfb4a06d",
  "_type": "organizationMember",
  "status": "invited",
},

and it could change depending on the member on the list that you’re currently viewing/editing.

// member 2
{
  "_key": "19fc3ebbe252",
  "_type": "organizationMember",
  "status": "invited",
},

so on, and so forth.

Now, what’s left is we’ll just have to check the status key and depending on its value, we’ll be able to show our dateAccepted field when it’s set to accepted.

And so to wrap things up!

{
  name: "dateAccepted",
  title: "Date Accepted",
  type: "datetime",
  hidden: ({ document, value }) => {
    // Grabs the current object we're editing based on
    // the current value of the field
    const member = document.members.find(
      (member) => member.dateAccepted === value
    );
    return member?.status !== "accepted";
  },
},

Voila! 💪😊

What now?

This example is pretty use case edge and in my opinion, it pays well to get a deeper understanding from the official documentation at the Sanity.io’s website guide so I advise that you go and check it out. Thank you! I hope this post helps…

Other guides by author

Creating my first Sanity.io plugin

I created my very first Sanity plugin and this article details out my experience - the problems I encountered and how I solved them. But yeah, just really scratching my own itch!

Dorell James
Go to Creating my first Sanity.io plugin

Dynamic GROQ Query in JavaScript

As we get to use GROQ more and more, it's inevitable when we get ourselves to situations where we need to construct queries dynamically. Here's how you make dynamic GROQ query in JavaScript.

Dorell James
Go to Dynamic GROQ Query in JavaScript

GROQ - a GraphQL alternative?

Heard of GROQ? How can it be used as an alternative to GraphQL? This article will not only introduce you to GROQ but you'll also learn to hopefully appreciate it. Truly a hidden gem out there!

This is an external link at:www.dorelljames.com
Dorell James
Go to GROQ - a GraphQL alternative?