Sanity GROQ: How do i get drafts for the array of references in a document?

1.4k Views Asked by At

I have a document type page which contains an array of blocks that are the references to other object types. When i fetch the data for page document, it returns draft data for document but not for the references that are in array. I have written query like this which returns me both drafts and non-drafts data for document:

*[_type == "page" && slug.current == "${querySlug === '/' ? 'home' : querySlug}"] {
  _id,
  title,
  description,
  showSubNav,
  subNavigation[] -> {slug, title},
  blocks[] -> {
    ...,
    heroCardBlock -> {...},
    oneColumnContent -> {...},
    featuredNews -> {...},
    newsCategories[] -> {...},
    newsList[] -> {..., selectedCategory -> {...}},
    caseStudiesListSource[] -> {...},
  }
}

This returns drafts and non-drafts data for page document and drafts are available for non-referenced blocks e.g title, description, showSubNav etc but for subNavigation and blocks array which are array of references to other object types, draft data is not being returned only published data is returned in query.

My sanity desk structure is like this: Sanity Desk Structure

How can i get draft data for these references?

2

There are 2 best solutions below

0
On

The dereference operator (->) will always return published content only. To get draft content you'd need to use a subquery (and the query must be authenticated, though if you're getting drafts of the page type back then that must be the case).

It's probably easiest to consider a simpler example, which you can then expand to your larger query. If we consider this:

*[_type == "page"] {
  _id,
  title,
  blocks[]->{
    heroCardBlock->,
  }
}

I'd expect you to get back your published heroCardBlock references. This revision should highlight the difference between getting back published and draft references:

*[_type == "page"] {
  _id,
  title,
  blocks[]->{
    'published': heroCardBlock->,
    'draft': *[_type == '<HERO_CARD_BLOCK_TYPE>' && _id in path('drafts.' + ^.^.heroCardBlock._ref)][0]
  }
}

I don't know what <HERO_CARD_BLOCK_TYPE> is but you'll want to specify it to help make this query more efficient. The double caret (^.^.) is needed to traverse twice up to the proper scope. The [0] is needed because the draft subquery will return an array even though it will always only be one document; specifying this causes published and draft to be formatted the same.

0
On

Based on Geoff Ball's answer and this page: https://www.sanity.io/schemas/fetch-the-draft-or-published-version-of-a-document-Pb0aymVu0PGBy9kYL3Azh

We can do it like this

*[_type == "page"] {
  ...,
  blocks[]{...coalesce(*[_id == 'drafts.' + ^._ref][0], *[_id == ^._ref][0])}
}

and it will look like the result of the following, but with drafts preferred

*[_type == "page"] {
  ...,
  blocks[]->
}

You can even use the { ... } syntax after the -> or the [0])}!