✨Discover storytelling in the AI age with Pixar's Matthew Luhn at Sanity Connect, May 8thβ€”register now

Querying nested draft documents in Sanity using GraphQL Apollo client

16 replies
Last updated: Jul 28, 2022
Hey πŸ™‚ Quick simple question:We are using Sanity in next.js project, and we are fetching data from sanity using graphql apollo client. I'm implementing now live-preview. And there is an question.
I've implemented fetching drafts documents in qgl query by using is_draft filter:


  allPage(limit: 1, where: {_: { is_draft: $isDraft }, slug: { current: { eq: $slug } } }) {
But, i have also nested documents in Page document in form:


Page {
  slug,
  title,
  contentPlaceholder[] {
    Banner (Document)
    Section (Document)
    Cards (object)
    ...others (Documents and objects
  }
}
And if i am fetching all page data (with objects/documents in contentPaceholder field) All of these nested
objects are properly fetched (in drafts) but all of nested documents are fetched in last published version. I need to know how to get also drafts of nested documents using sanity graphql api πŸ™‚
Jul 21, 2022, 1:50 PM
The example query is:

query GetPageBySlug($slug: String, $isDraft: Boolean = false) {
  allPage(limit: 1, where: {_: { is_draft: $isDraft }, slug: { current: { eq: $slug } } }) {
    title,
    slug {
      current
    }  
    placeholderContent {
      __typename,
      ...BannerFragment,
      ...CardsFragment,
      ...[etc]
    }
  }
}
Jul 21, 2022, 1:51 PM
You can use filters for those in the same way you did in allPage.
https://www.sanity.io/docs/graphql#59b6c9e5ba43
Jul 26, 2022, 1:30 PM
Are you set on graphQL or maybe you would like to give GROQ a try πŸ˜‰
Jul 26, 2022, 1:32 PM
Thank you for response
user J
. unfortunately my project team has decided to use GQL in this project. I'm trying to build proper query with filter for nested value. (But i'm newbie in both gql and sanity). Basing on documentation i've created this:
query GetPageBySlug($slug: String, $idMatch: ID = "") {
  allPage(limit: 1, where: { _id: { matches: $idMatch }, slug: { current: { eq: $slug } } }) {
    _id
    slug {
      current
    }
    title
    placeholderContent(where: {
      _id: { matches: $idMatch }
    }) {
      __typename
      ...PostFragment
      ...TestimonialsFragment
      ...BannerFragment
[...]
    }
  }
} 
But i am receiving "Unknown argument \"where\" on field \"placeholderContent\" of type \"Page\"."" error.

This is schema for PlaceholderContent:

{
      name: 'placeholderContent',
      title: 'Content Placeholder',
      type: 'array',
      of: placeholderContentTypes,
    },
where placeholderContentTypes are:

  {
    type: 'reference',
    to: [
      { type: 'post' },
      { type: 'banner' },
      { type: 'testimonials' },
      { type: 'questionAnswers' },
      { type: 'slider' },
      { type: 'logotypes' },
    ],
  },
  { type: 'sidedSection' },
  { type: 'webinars' },,
  { type: 'contactForm' },
...
];
if i can't use Where filter for array or object and documents, how can i filter these items by ID's to match "draft"?
Jul 26, 2022, 2:08 PM
user J
Hey πŸ™‚Small update: I got permission to use groq for this query. Here's an example of query:

    const test = await sanityClient.fetch(groq`
      *[_type == "page" && slug.current == $slug && _id in path('drafts.**')][0] {
        _id,
        title,
        slug,
        metadata,
        'placeholderContent': placeholderContent[] {
          _type == 'reference' => @->, // I want to fetch draft
          _type != 'reference' => @,
        }
      }
    `, { slug: routes.privacy_policy })
Jul 27, 2022, 1:47 PM
have you tested your first ever groq query in your vision tool in the studio yet?
Jul 27, 2022, 1:52 PM
Nope, but i've tested ^that query in our project and it fetches data well, but still i'm boxing with fetching drafts for references πŸ™‚
Jul 27, 2022, 1:54 PM
user J
I almost got it:
 *[_type == "page" && slug.current == $slug && _id in path($idMatch)][0] {
        _id,
        title,
        slug,
        metadata,
        'placeholderContent': placeholderContent[] {
          ...*[_id in [^._ref, "drafts." + ^._ref]][0],
          _type != 'reference' => @,
        }
      }
But there is one last issue:

There is an example "placeholderContent" response:

[
  {
    "_createdAt": "2022-07-08T07:46:30Z",
    "_id": "drafts.fa61378c-20ed-4450-b0cd-e20c432b3456",
    "_rev": "7xboex-rf2-kvy-knu-ny0ltgjvb",
    "_type": "banner",

    "slug": {
      "_type": "slug",
      "current": "/privacy-policy"
    },
    "subtext": "test",
    "title": [
      {
        "_key": "071676100bbf",
        "_type": "block",
        "children": [...]
  },
  {
    "_createdAt": "2022-07-27T14:28:58Z",
    "_id": "68a88070-2cb4-4018-928e-3fbb8e975488",
    "_rev": "xrNOqW8MxhVZd5cuCRwmtb",
    "_type": "testimonials",
    "_updatedAt": "2022-07-27T14:28:58Z",
    "items": [
      {
        "_key": "0c041f845f96",
        "_type": "testimonial",
        "author": "test",
        "date": "2022-06-29",
        "opinion": "test"
      }
    ],
    "title": "test"
  }
]
And as you can see i have a part
...*[_id in [^._ref, "drafts." + ^._ref]][0]
in my query. And - if i select [0] in array -> Only first document in placeholderContent array is fetched in draft version. If i pass [1] - only second document is fetched in draft (and first document is fetched in published version). This is probably the last thing to make it fully working
Jul 27, 2022, 3:16 PM
what do you want to get exactly from the placholder array?
Jul 27, 2022, 4:57 PM
I need to know how to get also drafts of nested documents
...*[_id in ^._ref && _id in path($"drafts.**")]
this should do the trick!
Jul 27, 2022, 5:09 PM
I have it implemented and fully working, huge thanks
user J
!
Can i resolve all images references in query?

The asset for image looks like that:

"asset": {
      "_ref": "image-df9f14aaebefb17704af30c01d6fcd7eca624afe-3000x4542-jpg",
      "_type": "reference"
    }
But there we have types autogenerated from graphql -> There is a way to "autoresolve" image references and get full data like in graphql instead of asset reference?
Jul 28, 2022, 7:29 AM
Jup:
//get the whole image object with all metadata etc.
'img': img.asset->
//get only the image url 
'img': img.asset->url
I would highly reccomend
user B
’s Learn GROQ in 45 minutes πŸ™‚ this is how I learnt the most and with nice examples to play with!
Jul 28, 2022, 8:03 AM
Okay πŸ™‚ And probably my last question:This is, how my query looks like:

*[_type == "page" && slug.current == $slug && _id in path($idMatch)][0] {
        _id,
        title,
        slug,
        metadata,
        'placeholderContent': placeholderContent[] {
          ...coalesce(
            *[_id in ["drafts." + ^._ref]][0],
            *[_id in [^._ref]][0]
          ) {
            ...,
            "__typename": _type,
            "titleRaw": title,
            "textRaw": text,
            "marketingAgreementRaw": marketingAgreement,
            "dataProcessingAgreementRaw": dataProcessingAgreement,
            "contentRaw": content,
            "bodyRaw": body,
            "image": {
              "alt": image.alt,
              "asset": image.asset->ur
            }
            
          },
          _type != 'reference' => {
            ...,
            "__typename": _type,
             "titleRaw": title,
            "textRaw": text,
            "marketingAgreementRaw": marketingAgreement,
            "dataProcessingAgreementRaw": dataProcessingAgreement,
            "contentRaw": content,
            "bodyRaw": body,
              
          },
        }
      }
And the question is:
I have many different Documents in placeholderContent. And we want to comply with the types autogenerated from gql queries. And for example: all of "blockContent" have added "Raw" by gql, and we have to rename "text" to "textRaw" - but only for documents having blockContent text. For now, "textRaw" is added to all of array items, no matter if "text" exists or not. Is there a way to make it better? Or maybe rename all blockContents automatically?
Jul 28, 2022, 8:22 AM
Hllo again
user J
πŸ™‚ Hope that you have a nice day πŸ™‚ I've got a question. I'm looking for a feature to resolve all references in groq query, no matter how deep is it. I've found this topic: https://github.com/sanity-io/GROQ/issues/21 Is it implemented? Or there's something similar maybe?
Jul 28, 2022, 5:35 PM
Could you please post this as a separate thread in help? it is really hard to keep up with this thread now and it is a different issue πŸ™‚I need to go now, but I will be back tomorrow.
Jul 28, 2022, 8:43 PM
pink panther goodbye
Jul 28, 2022, 8:43 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?