Accessing array index in Sanity projections

4 replies
Last updated: Jul 26, 2021
Is there a way to access the index of an item in an array in it's projection? For example:
someArray[] {
  someCondition => {
    // this is the thing I want, but I also need the next item in the list the user defined
    nextItem: someArray[currentIndex + 1]
  }

  !someCondition => {
    // mark I don't want this
    marker: true
  }
}[marker!=true]
Or, even better:

someArray[someCondition] {
  // Access the item index of the original array before I filtered it
  nextItem: [(index @ in someArray) + 1]
}
Right now it seems like the only way to do this is to deliver the entire array to my front-end and filter it client-side, which is wasteful on bandwidth.

The only bandwidth-friendly way I can do this without an index is to do multiple queries; one for the shape of the array and others for the specific data I want to fetch. But it would still be much better to do it in a single query.

// shape query
someArray[] {
  // we only get the shape of the array here
  _type, someIdentifier
}

// data query
*[someIdentifier] {...}
*[someIdentifier2] {...}
Jul 26, 2021, 5:51 PM
Keep in mind that accessing a specific item based on a index is never safe or 100% accurate. It’s in general bad practice to use these as values or indentifiers. What are you trying to do? Why don’t create based on a unique tag/category or something which is more safe and better to use?
Jul 26, 2021, 6:45 PM
It allows you to do things based on how the user ordered a reorderable array (ex. preloading the next page client-side). Accessing items by index in separate queries is unsafe, but if you could (in one query) include a unique identifier to sibling items by index, then that would be safe(r)
Jul 26, 2021, 6:50 PM
In my case, I have an issue that has many articles, and each article needs to link on the front-end to the next article in the list. Since the ordering is user-defined there's no easy way to specify this relationship. I'd rather not force the user to click on every article and directly reference the next thing in the array.
Jul 26, 2021, 6:52 PM
For anyone else who has this issue, I fixed it by including the array shape in the same query as the main data; having the types for the whole array makes it more flexible anyway.
[documentFilter] {
  ...array[filterForItem][0],
  "documentInfo": @ {
     ...,
     "arrayShape": ^.array[] {
       _type, slug
     }
   }
}
Jul 26, 2021, 7:17 PM

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?