Next.js Discord

Discord Forum

Caching by ID: unstable_cache with id in dependency array + revalidateTag

Unanswered
Sloth bear posted this in #help-forum
Open in Discord
Sloth bearOP
I have the following quetion.

Let's say I have the unstable_cache function for checking if an onboardingSurvey was filled by a user:

It accepts:

1) user_id which is added to the cache keyParts as well as the hasCompletedOnboardingSurvey
2) I create the tag to revalidate based on the function name hasCompletedOnboardingSurvey

  const hasCompletedOnboardingSurvey = unstable_cache(
    async ({ userId }: { userId: string }) => {
      const onboardingSurveysData = await db
        .select({
          id: onboardingSurveys.id,
        })
        .from(onboardingSurveys)
        .where(eq(onboardingSurveys.userId, userId))

      return onboardingSurveysData.length > 0
    },
    ['hasCompletedOnboardingSurvey'],
    {
      tags: ['hasCompletedOnboardingSurvey'],
    },
  )


When a user clicks the don't show button in a client component, I am running the following server action, where I call revalidateTag('hasCompletedOnboardingSurvey'):

async function saveOnboardingSurvey({
  data
}: {
  data: TForm
}) {
  'use server'

  const user = await getUser()

  await db.insert(onboardingSurveys).values({
    ...data,
    userId: user.id,
    createdAt: new Date(),
  })

  revalidateTag('hasCompletedOnboardingSurvey')
  redirect('/campaigns')
}


My current understanding is that this will invalidate the cache for ALL USERS since I cannot pass in the userId as a tag. Is this correct? How would I be able to only revalidate the data cache for a specific user and not every user?

Thanks 🙏

2 Replies

@Sloth bear I have the following quetion. Let's say I have the `unstable_cache` function for checking if an onboardingSurvey was filled by a user: It accepts: 1) `user_id` which is added to the cache `keyParts` as well as the `hasCompletedOnboardingSurvey` 2) I create the tag to `revalidate` based on the function name `hasCompletedOnboardingSurvey` const hasCompletedOnboardingSurvey = unstable_cache( async ({ userId }: { userId: string }) => { const onboardingSurveysData = await db .select({ id: onboardingSurveys.id, }) .from(onboardingSurveys) .where(eq(onboardingSurveys.userId, userId)) return onboardingSurveysData.length > 0 }, ['hasCompletedOnboardingSurvey'], { tags: ['hasCompletedOnboardingSurvey'], }, ) When a user clicks the don't show button in a client component, I am running the following server action, where I call `revalidateTag('hasCompletedOnboardingSurvey')`: async function saveOnboardingSurvey({ data }: { data: TForm }) { 'use server' const user = await getUser() await db.insert(onboardingSurveys).values({ ...data, userId: user.id, createdAt: new Date(), }) revalidateTag('hasCompletedOnboardingSurvey') redirect('/campaigns') } My current understanding is that this will invalidate the cache for ALL USERS since I cannot pass in the `userId` as a tag. Is this correct? How would I be able to only revalidate the data cache for a specific user and not every user? Thanks 🙏
hi, try this
const hasCompletedOnboardingSurvey = (props: { userId: string }) =>
  unstable_cache(
    async ({ userId }: { userId: string }) => {
      const onboardingSurveysData = await db
        .select({
          id: onboardingSurveys.id,
        })
        .from(onboardingSurveys)
        .where(eq(onboardingSurveys.userId, userId));

      return onboardingSurveysData.length > 0;
    },
    ["hasCompletedOnboardingSurvey"],
    {
      tags: [`hasCompletedOnboardingSurvey-${props.userId}`],
    }
  )(props);
and this when you try to revalidate
revalidateTag(`hasCompletedOnboardingSurvey-${user.id}`)