Conditional filtering in Next.js function for fetching posts

3 replies
Last updated: Jun 26, 2024
I have a function in Next JS for fetching posts.

export async function getPosts(start: number = 0, end: number = 9, _id?: string) {
	const getPostsQuery = groq`
		// Get posts         That are in the selected category   And order them by published date
		*[_type == "post" && $categoryId in categories[]._ref] | order(publishedDate desc) {
			title,
			slug {
				current
			},
			publishedDate,
			shortDescription,
			cardImage {
				...,
				asset-> {
					...,
				}
			}
		}[$start...$end]
	`

	return client.fetch<GetPostsQueryResult>(
		getPostsQuery,
		{ start, end, categoryId: _id },
		{
			next: {
				tags: ['posts'],
				revalidate: 60,
			},
		}
	)
}
I'm conditionally passing in an "_id" depending on whether I want to fetch only posts that have a certain category. This works great for when it's passed in, but breaks when nothing is passed in.

It's specifically
$categoryId in categories[]._ref
this part of the query that is fetching based on the passed ID.
Can I make this filtering conditional, and stop it from doing this filter when nothing is passed as an ID?
Jun 25, 2024, 2:03 PM
I've managed to do it by altering it to this:

export async function getPosts(start: number = 0, end: number = 9, _id?: string) {
	const getPostsQuery = groq`
		// Get posts         That are in the selected category   And order them by published date
		*[_type == "post" ${_id ? ' && $categoryId in categories[]._ref' : ''}] | order(publishedDate desc) {
			title,
			slug {
				current
			},
			publishedDate,
			shortDescription,
			cardImage {
				...,
				asset-> {
					...,
					metadata {
						...,
					}
				}
			}
		}[$start...$end]
	`

	return client.fetch<GetPostsQueryResult>(
		getPostsQuery,
		{ start, end, categoryId: _id ? _id : 'undefined' },
		{
			next: {
				tags: ['posts'],
				revalidate: 60,
			},
		}
	)
}
For me this, this is a bit of a hacky solution. Can this be done in a more "natural" way?
Jun 25, 2024, 2:13 PM
Template literals are the way to go here.
Jun 25, 2024, 3:24 PM
Do you know when the new sanity typegen will have support for this? As currently, using string interpolation isn't supported and stops types from being generated
Jun 26, 2024, 7:22 AM

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?