Next.js Discord

Discord Forum

Updating issue

Answered
i_lost_to_loba_kreygasm posted this in #help-forum
Open in Discord
I am facing issues with updating the DOM . If I insert a new document in the mongo Database,the network is fetching the updated documents but I don't see it in the DOM
Answered by B33fb0n3
perfect. As you can see: the relevant pages where the user can see your data are static. That means, that they will build once (during build time) and then just served. In dev mode, it will be nearly always dynamic, that's why it still works in dev mode.

So when you change data you also want to "rebuild" that specific page. You can do that by "revalidating" the data. And that works with a function from nextjs:
revalidatePath("/your/path");

Call the function, when you want that your page should show new data.

Another thing you can do: revalidate that data after a specifc amount of time

-- Edit
Also it would be possible to make it dynamic like this: https://nextjs-forum.com/post/1311983350763749437#message-1312021790876373023
View full answer

46 Replies

@B33fb0n3 hi again
can you share some code? On how you insert the page, how you update the documents and how you load & show them
import db from "@/mongo";
export async function GET(req) {
    const itemsCollection =await db.collection("items").find().toArray();   
    return Response.json({items:itemsCollection})
 
  }
this is the api route file
// App/page.js
async function Home() {
  let { items, error, loading } = await getItems();


  return <Container py={16} px={[4, 16, 16]} maxW={1260}>
    <Box maxW={940} mx={'auto'}>
      <Heading mb={8} fontSize={'4xl'}>Items</Heading>
      <Flex mx={'auto'} justifyContent={'center'} gap={'20px'} wrap={'wrap'} >
        {loading ? (
          <p>Loading...</p>
        ) : error ? (
          <p>{error}</p>
        ) : (
          items.map((item, index) => (
            <GreenCard
              key={index}
              name={item.name}
              description={item.description}
              price={item.price}
              imageUrl={item.imageUrl}
            />
          ))
        )}

      </Flex>
    </Box>

  </Container>
}
export default Home;
// this is the fetch helper file
export async function getItems(category){
    let items=[];
    let error=null;
    let loading=false;
    try{
      loading=true;  
      const response = await fetch(`${process.env.NEXT_PUBLIC_URL}/api/get_items`);
      
      if (!response.ok) {
        throw new Error(`Failed to fetch data: ${response.status}`);
      }
      items = await response.json();
      items=category?items.items.filter(item => item.category===category):items.items;
      loading=false;
    }
    catch(err){
      error=err.message;
    }
   
    return {items,error,loading}
}
it works fine when I push the code for deployment
I am updating the mongo DB from the website
here is the deployed link if you wanna check the network tab
Inside your page.js can you replace the await getItems() with:
await db.collection("items").find().toArray()

Remove the "loading" part for a moment. Tell me when done
not working 😦
i wonder if its because I am using server component
@i_lost_to_loba_kreygasm done
great. It works like expected, correct? If yes, you can clearly delete everything that you used as wrappers (router handler & the function), because in SSR you don't need it (as you can see).

The page itself is SSR (server side rendered). So the server calculates everything first and then send this data to the client (so no loading inside your function needed as well). And when you now change something inside your database, the server won't notice.
So a page reload is needed to show the new data.
or
You can fetch the data clientside using a clientside fetching library like SWR or react query. With that you can refetch the data in an interval or when the page is refocused or ...

Why it works in dev mode? In dev mode the page automatically refreshes in the background (fast refresh)
but refreshing page doesnt work
ok , so the data from the DB is fetched on server side once during deployment , is that why ?
when you build your page (next build) which icon has the specific page? Static, Dynamic, ...?
@B33fb0n3 when you build your page (next build) which icon has the specific page? Static, Dynamic, ...?
i hope these logs help u
@i_lost_to_loba_kreygasm i hope these logs help u
that looks good, but I need the logs at the end. It looks more like this (of course with your routes):
here
@i_lost_to_loba_kreygasm need more ?
perfect. As you can see: the relevant pages where the user can see your data are static. That means, that they will build once (during build time) and then just served. In dev mode, it will be nearly always dynamic, that's why it still works in dev mode.

So when you change data you also want to "rebuild" that specific page. You can do that by "revalidating" the data. And that works with a function from nextjs:
revalidatePath("/your/path");

Call the function, when you want that your page should show new data.

Another thing you can do: revalidate that data after a specifc amount of time

-- Edit
Also it would be possible to make it dynamic like this: https://nextjs-forum.com/post/1311983350763749437#message-1312021790876373023
Answer
@i_lost_to_loba_kreygasm where do I use this function? 😔
you can use it only serverside and then where you like: in route handlers, server actions, (server components <-- technically possible, but I never had a use case), ...
@B33fb0n3 you can use it only serverside and then where you like: in route handlers, server actions, (server components <-- technically possible, but I never had a use case), ...
 import { revalidatePath } from "next/cache";
import db from "@/mongo";
export async function GET(req) {
    const itemsCollection =await db.collection("items").find().toArray();
    revalidatePath('/')   
    return Response.json({items:itemsCollection})
 
  }
is this correct ? my home page is dependent on the data from the route
yeah i see it now
can the revalidatePath function accept array ? since i have 4 pages dependent on the data
@i_lost_to_loba_kreygasm js import { revalidatePath } from "next/cache"; import db from "@/mongo"; export async function GET(req) { const itemsCollection =await db.collection("items").find().toArray(); revalidatePath('/') return Response.json({items:itemsCollection}) } is this correct ? my home page is dependent on the data from the route
no. You page right now should look like this:
// App/page.js
async function Home() {
  let items = await db.collection("items").find().toArray();


  return <Container py={16} px={[4, 16, 16]} maxW={1260}>
    <Box maxW={940} mx={'auto'}>
      <Heading mb={8} fontSize={'4xl'}>Items</Heading>
      <Flex mx={'auto'} justifyContent={'center'} gap={'20px'} wrap={'wrap'} >
        {
          items.map((item, index) => (
            <GreenCard
              key={index}
              name={item.name}
              description={item.description}
              price={item.price}
              imageUrl={item.imageUrl}
            />
          ))
        }

      </Flex>
    </Box>

  </Container>
}
export default Home;

We make it a bit easier. Add this on top:
// App/page.js

export const dynamic = 'force-dynamic'

async function Home() {
  ....
}

Then it will work in production like it is in dev mode
ok , but what does revalidatePath do ? so by revalidating , my pages are not built once on serverside during building?
@i_lost_to_loba_kreygasm ok , but what does `revalidatePath` do ? so by revalidating , my pages are not built once on serverside during building?
imagine the building process (simplified): vercel now create html, css and js. When a user visits your page, vercel shows the created html, css and js. And that over and over again. Even if the data changed in the background, the html, css and js will stay the same.

With revalidatePath vercel throws this html, css and js into the trash bin and creates a new version of your page. This new version will be served then over and over again
so with revalidatePath , the data is fetched over and over whenever there is a new request?
@i_lost_to_loba_kreygasm so with `revalidatePath ` , the data is fetched over and over whenever there is a new request?
when you use it like you showed me, then yes.

However using
export const dynamic = 'force-dynamic'

makes the route dynamic and like that is also refetches everytime someone visits the page
i understand that the dynamic refetches every time
when you use it like you showed me, then yes. but wdym by this ?
@i_lost_to_loba_kreygasm `when you use it like you showed me, then yes.` but wdym by this ?
you wanted to call it whenever you call your route handler. And that happens each page visit (with your old page.js)
so it does run over and over
i think i understand now
@i_lost_to_loba_kreygasm so it does run over and over
when you use it like you showed me, then yes
But you really should prefer the use of
export const dynamic = 'force-dynamic'

Instead of revalidating each time. As your (old) page.js had a lot of irrelevant wrappers that are hard to maintain the use of this variables is recommended
i got you 🙂
mark its solved
thank you for sticking with me 🙂
sure thing