Next.js Discord

Discord Forum

Revalidate data in multiple server components after mutation in a server action

Unanswered
Asiatic Lion posted this in #help-forum
Open in Discord
Asiatic LionOP
My app has a dashboard and a public page, I am using prisma ORM, I fetch my data in server components like this:

 Blogpost Dashboard Page
import {prisma} from "@/lib/prisma";

async function DashboardBlogPage(){
const data = await prisma.blogs.findMany();
return (
<div>
<CreateBlogPostForm/>
<Suspense fallback={<LoadingSkeleton/>
<BlogPostList/>
</Suspense>
</div>
}


 Blogpost Public Page
import {prisma} from "@/lib/prisma";

async function PublicBlogPage(){
const data = await prisma.blogs.findMany():
return (
<div>
<CreateBlogPostForm/>
<UpdateBlogPostForm/>
<Suspense fallback={<LoadingSkeleton/>
<BlogPostList/>
</Suspense>
</div>
}


 BlogPost Server Actions
'use server';
import {prisma} from '@/lib/prisma';
import {revalidatePath} from 'next/cache';

export async function updateBlogPost(blogPostId, blogPostContent){
try{
await prisma.blogs.update({
where:{id: String(blogPostId)}
});
revalidatePath('/public/blogs');
catch(error){
throw error;
}
}


I've been trying to make this to work for hours now. I simply want my blogPost data to get updated to the latest when I update it in my server action. But it is not working. I am doing a route.refresh in my from submission function in my client component <UpdateBlogpostForm/> and the blogpost page in my dashboard gets updated instantly when I do the update expect for my public blog post page.

6 Replies

@Asiatic Lion My app has a dashboard and a public page, I am using prisma ORM, I fetch my data in server components like this: Blogpost Dashboard Page import {prisma} from "@/lib/prisma"; async function DashboardBlogPage(){ const data = await prisma.blogs.findMany(); return ( <div> <CreateBlogPostForm/> <Suspense fallback={<LoadingSkeleton/> <BlogPostList/> </Suspense> </div> } Blogpost Public Page import {prisma} from "@/lib/prisma"; async function PublicBlogPage(){ const data = await prisma.blogs.findMany(): return ( <div> <CreateBlogPostForm/> <UpdateBlogPostForm/> <Suspense fallback={<LoadingSkeleton/> <BlogPostList/> </Suspense> </div> } BlogPost Server Actions 'use server'; import {prisma} from '@/lib/prisma'; import {revalidatePath} from 'next/cache'; export async function updateBlogPost(blogPostId, blogPostContent){ try{ await prisma.blogs.update({ where:{id: String(blogPostId)} }); revalidatePath('/public/blogs'); catch(error){ throw error; } } I've been trying to make this to work for hours now. I simply want my blogPost data to get updated to the latest when I update it in my server action. But it is not working. I am doing a route.refresh in my from submission function in my client component <UpdateBlogpostForm/> and the blogpost page in my dashboard gets updated instantly when I do the update expect for my public blog post page.
its preferred to attach a tag to prisma.blogs.findMany by either using unstable_cache or "use cache" and then use updateTag() in server actions in the latest version.

if you still rather use revalidatePath, best you can do is to revalidate all affected paths that uses the blogPost data
async function DashboardBlogPage(){
  const data = await unstable_cache(
    () => prisma.blogs.findMany(), undefined, 
    { tags: ['allblogs'] })();
  return (
  <div>
    <CreateBlogPostForm/>
    <Suspense fallback={<LoadingSkeleton/>}
      <BlogPostList/>
    </Suspense>
  </div>
}

async function PublicBlogPage(){
  const data = await unstable_cache(
    () => prisma.blogs.findMany(), undefined, 
    { tags: ['allblogs'] })();
  return (
  <div>
    <CreateBlogPostForm/>
    <UpdateBlogPostForm/>
    <Suspense fallback={<LoadingSkeleton/>
      <BlogPostList/>  
    </Suspense>
  </div>
}

'use server';
import {prisma} from '@/lib/prisma';
import {revalidatePath} from 'next/cache';

export async function updateBlogPost(blogPostId, blogPostContent){
  try{
    await prisma.blogs.update({
      where:{id: String(blogPostId)}
    });
    updateTag('allblogs');
  catch(error){
    throw error;
  }
}
Cinnamon Teal
Doesn't revalidaPath(/, "layout") work either? That way you are basically revalidating everything.

export async function updateBlogPost(blogPostId, blogPostContent) {
  try {
    await prisma.blogs.update({
      where: { id: String(blogPostId) },
    })

    revalidatePath("/", layout)
  } catch (error) {
    throw error
  }
}
yeah that should work too but thats like refreshing all the pages even those who aren't affected
at worst you can just do revalidatePath('/')
Asiatic LionOP
Thanks @aardani
I implemented the solution but I noticed that when I run the code and make an update on my dashboard blog page, the public blog post page data doesn’t get updated instantly. I have to do a manual refresh or back and forth navigation before I see the updated content.
Is that how it should work?
I expected my blog content to update to the latest content whenever I update it and reflect the changes instantly on the pages they’re being fetched.