Next.js Conf 2024: Your app should be Live by Default – Watch Keynote

Using values from a Groq query in a separate query for a blog post.

13 replies
Last updated: Jul 15, 2021
What would be the appropriate way to use a value from a groq query in a separate query. for example i'm getting the date of a blog post, and i need another query to get the next post based on published date
Jul 15, 2021, 6:48 PM
If you want it to be a separate query, you could pull the desired field into your next query using query parameters or template literals. However, it could also work inside the same query (if that works in your use case) by using multiple projections. For example, this would return all posts with a date more recent than the post at index 5:

*[_type == 'post'] | order(date desc)[5] {
  date,
} {
  'result': *[_type == 'post' && date > ^.date]
}
Jul 15, 2021, 8:13 PM
ideally yea, i would like all in the same query. what i would really want is to return all the data i currently get for the specific post, along with a slug for the previous and next post
Jul 15, 2021, 8:17 PM
looking into multiple projections
Jul 15, 2021, 8:17 PM
obviously not ideal currently
const slug = route.params.episode;
const query = groq`*[_type == "episode" && slug.current == "${slug}" ][0]{_id, title, "author": author->, slug, sponsor->,  mainImage, episodeURL, episodeTypes->, publishedAt, body }`;
const episode = await $sanity.fetch(query)
const next = groq`*[_type == "episode" && publishedAt > "${await episode.publishedAt}"][0]{slug, title}`
const nextEp = await $sanity.fetch(next);
const prev = groq`*[_type == "episode" && publishedAt < "${await episode.publishedAt}"][0]{slug, title}`
const prevEp = await $sanity.fetch(prev);
Jul 15, 2021, 8:26 PM
obviously not ideal currently
const slug = route.params.episode;
const query = groq`*[_type == "episode" && slug.current == "${slug}" ][0]{_id, title, "author": author->, slug, sponsor->,  mainImage, episodeURL, episodeTypes->, publishedAt, body }`;
const episode = await $sanity.fetch(query)
const next = groq`*[_type == "episode" && publishedAt > "${await episode.publishedAt}"][0]{slug, title}`
const nextEp = await $sanity.fetch(next);
const prev = groq`*[_type == "episode" && publishedAt < "${await episode.publishedAt}"][0]{slug, title}`
const prevEp = await $sanity.fetch(prev);
Jul 15, 2021, 8:26 PM
I’m using
_createdAt
because it uses datetime—which would be pretty necessary for a technique like this—but what about:

*[_type == 'post'] | order(_createdAt desc)[5] {
  'post': @,
  'next': *[_type == 'post' && _createdAt > ^._createdAt] | order(_createdAt asc)[0],
  'prev': *[_type == 'post' && _createdAt < ^._createdAt] | order(_createdAt desc)[0],
}
Jul 15, 2021, 8:30 PM
Though in your case, you would use a projection to just return
slug.current
for
prev
and
next
.
Jul 15, 2021, 8:31 PM
i think i see what you're getting around, going to play around with your query a bit
Jul 15, 2021, 8:32 PM
still pretty new to sanity, but this is helpful
Jul 15, 2021, 8:32 PM
*[_type == 'episode' && slug.current == "${slug}"]{_id, title, "author": author->, slug, sponsor->,  mainImage, episodeURL, episodeTypes->, publishedAt, body } | order(publishedAt desc)[0] {
    'episode': @,
    'next': *[_type == 'episode' && publishedAt > ^.publishedAt]{slug, title, publishedAt} | order(publishedAt asc)[0],
    'prev': *[_type == 'episode' && publishedAt < ^.publishedAt]{slug, title, publishedAt} | order(publishedAt desc)[0],
  }
Jul 15, 2021, 9:18 PM
went with above, i think this works nicely. and man i love the simplicity.
Jul 15, 2021, 9:18 PM
Nice! Glad to hear it, Matt. Happy building!
Jul 15, 2021, 9:44 PM
Nice! Glad to hear it, Matt. Happy building!
Jul 15, 2021, 9:44 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?