Help with unstable_cache and revalidateTag
Answered
Northern Wheatear posted this in #help-forum
Northern WheatearOP
I've been using unstable_cache for a while and it works very well. This is the question in my mind. I have a query to the database which might return null for a specific row but that row will be populated soon enough. How can I omit the cache whenever the value from db is null and cache it once the value is set in db.
Thanks
Thanks
Answered by joulev
Not sure if that works, but this very likely will work
class SkipCacheError extends Error {}
…
const dataCacheFn = unstable_cache(async(id:string)=>{
const user = await getUserData(id)
if (!user) throw new SkipCacheError()
return user
},
["user-data-cache"],
{
revalidate: 60 * 60 * 24,
tags: ["user-data"],
}
);
async function getUser(userId) {
try {
const user = await dataCacheFn(userId)
return user
catch (e) {
if (e instanceof SkipCacheError) return null
throw e
}
}18 Replies
Northern WheatearOP
Will this work?
const dataCacheFn = unstable_cache(async(id:string)=>{
const user = await getUserData(id)
return user
},
["user-data-cache"],
{
revalidate: 60 * 60 * 24,
tags: ["user-data"],
}
);
const user = await dataCacheFn(userId)
if(!user) revalidateTag("user-data")no, you'll have to revalidate user-data
Northern WheatearOP
Sorry I meant that small typo
Northern WheatearOP
Thanks!!
But one doubt.... Doing so will revalidate every users cache right?
@Anay-208
You can instead set tag to that user id
Northern WheatearOP
But the tags part in unstable_cache is not dynamic right?
@Northern Wheatear But the tags part in unstable_cache is not dynamic right?
Short-eared Owl
You just need to make a wrapper function which takes the user id, calls the unstable_cache and then allows you to put the userId argument inside of the tags
@Northern Wheatear Will this work?
const dataCacheFn = unstable_cache(async(id:string)=>{
const user = await getUserData(id)
return user
},
["user-data-cache"],
{
revalidate: 60 * 60 * 24,
tags: ["user-data"],
}
);
const user = await dataCacheFn(userId)
if(!user) revalidateTag("user-data")
Not sure if that works, but this very likely will work
class SkipCacheError extends Error {}
…
const dataCacheFn = unstable_cache(async(id:string)=>{
const user = await getUserData(id)
if (!user) throw new SkipCacheError()
return user
},
["user-data-cache"],
{
revalidate: 60 * 60 * 24,
tags: ["user-data"],
}
);
async function getUser(userId) {
try {
const user = await dataCacheFn(userId)
return user
catch (e) {
if (e instanceof SkipCacheError) return null
throw e
}
}Answer
@Short-eared Owl You just need to make a wrapper function which takes the user id, calls the unstable_cache and then allows you to put the userId argument inside of the tags
Northern WheatearOP
I just did that... It works as expected. Thanks
@joulev Not sure if that works, but this very likely will work
tsx
class SkipCacheError extends Error {}
…
const dataCacheFn = unstable_cache(async(id:string)=>{
const user = await getUserData(id)
if (!user) throw new SkipCacheError()
return user
},
["user-data-cache"],
{
revalidate: 60 * 60 * 24,
tags: ["user-data"],
}
);
async function getUser(userId) {
try {
const user = await dataCacheFn(userId)
return user
catch (e) {
if (e instanceof SkipCacheError) return null
throw e
}
}
Northern WheatearOP
Throwing an error prevents it from caching right?
Interesting... Let me try this
Interesting... Let me try this
Northern WheatearOP
Yes this implementation works!
Thank a lot to both of you. Personally I think joulev's implementation is better as it doesn't store the cache in the first place