#Page only fetching MongoDB data at build time

1 messages · Page 1 of 1 (latest)

paper sandBOT
#

Hi @pine fox. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

To ensure that your page re-fetches data from MongoDB every time the page is refreshed, you need to use a data fetching strategy that runs on every request. In Next.js, you can achieve this by using getServerSideProps instead of fetching data directly in your component. This will ensure that the data is fetched on every request, both in development and in production.

Here's how you can modify your app/admin/page.tsx to use getServerSideProps:

import clientPromise from "../lib/mongodb";

interface UserData {
  _id: string;
  name: string;
  email: string;
}

async function getData() {
  const client = await clientPromise;
  const db = client.db("test");
  const databaseUsers = await db.collection("users").find({}).toArray();
  return databaseUsers;
}

export async function getServerSideProps() {
  const users = await getData();
  return {
    props: {
      users,
    },
  };
}

export default function Page({ users }: { users: UserData[] }) {
  return (
    <div>
      <h1>User List from MongoDB</h1>
      {users.map((user) => (
        <li className="py-2" key={user.name}>
          <p>{user.name}</p>
          <p>{user.email}</p>
          <p>{user.views}</p>
        </li>
      ))}
    </div>
  );
}

Explanation:

  • getServerSideProps: This function runs on the server on every request. It fetches the data from MongoDB and passes it as props to your page component.
  • Page Component: The Page component now receives the users data as props and renders it.

By using getServerSideProps, you ensure that the data is fetched on every request, both in development and in production, thus solving the issue of static data after the initial build.

#

@pine fox kapa.ai is still learning and improving, please let us know how it did by reacting below

pine fox
paper sandBOT
#

Let me check the knowledge base for you. One moment! :books:

#

It looks like you're encountering an issue because getServerSideProps is not supported in the app/ directory of Next.js. Instead, you should use the new data fetching methods provided by the App Router.

For server-side data fetching in the App Router, you can directly fetch data inside your component. Here’s how you can modify your app/admin/page.tsx to fetch data on every request:

import clientPromise from "../lib/mongodb";

interface UserData {
  _id: string;
  name: string;
  email: string;
}

async function getData() {
  const client = await clientPromise;
  const db = client.db("test");
  const databaseUsers = await db.collection("users").find({}).toArray();
  return databaseUsers;
}

export default async function Page() {
  const users: UserData[] = await getData();

  return (
    <div>
      <h1>User List from MongoDB</h1>
      <ul>
        {users.map((user) => (
          <li className="py-2" key={user._id}>
            <p>{user.name}</p>
            <p>{user.email}</p>
            <p>{user.views}</p>
          </li>
        ))}
      </ul>
    </div>
  );
}

Explanation:

  • Fetching Data: The getData function fetches data from MongoDB.
  • Page Component: The Page component calls getData and renders the fetched data.

This approach ensures that data is fetched on every request, both in development and in production, without relying on getServerSideProps.

For more details on data fetching in the App Router, you can refer to the Next.js documentation on data fetching (https://nextjs.org/docs/app/building-your-application/data-fetching/fetching).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@pine fox kapa.ai is still learning and improving, please let us know how it did by reacting below

pine fox
#

@paper sand thats exactly what i had in the first place that does not work

paper sandBOT
#

Let me check the knowledge base for you. One moment! :books:

#

Given that getServerSideProps is not supported in the app/ directory and your initial approach is not working as expected, you can use the fetch API directly within your server component to ensure data is fetched on every request.

Here's how you can modify your app/admin/page.tsx to ensure it fetches data on every request:

import clientPromise from "../lib/mongodb";

interface UserData {
  _id: string;
  name: string;
  email: string;
}

async function getData() {
  const client = await clientPromise;
  const db = client.db("test");
  const databaseUsers = await db.collection("users").find({}).toArray();
  return databaseUsers;
}

export default async function Page() {
  const users: UserData[] = await getData();

  return (
    <div>
      <h1>User List from MongoDB</h1>
      <ul>
        {users.map((user) => (
          <li className="py-2" key={user._id}>
            <p>{user.name}</p>
            <p>{user.email}</p>
            <p>{user.views}</p>
          </li>
        ))}
      </ul>
    </div>
  );
}

Explanation:

  • Server Component: By default, components in the app/ directory are server components. This means they run on the server and can fetch data directly.
  • Data Fetching: The getData function fetches data from MongoDB and is called within the Page component. This ensures that data is fetched on every request.

This approach should ensure that your data is fetched on every request, both in development and in production, without relying on getServerSideProps.

For more details on data fetching in the App Router, you can refer to the Next.js documentation on data fetching (https://nextjs.org/docs/app/building-your-application/data-fetching/fetching).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@pine fox kapa.ai is still learning and improving, please let us know how it did by reacting below

pine fox
#

@paper sand help me add revalidatePath to my data fetching maybe

paper sandBOT
#

Let me check the knowledge base for you. One moment! :books:

#

To ensure that your data is revalidated on-demand, you can use the revalidatePath function from the next/cache module. This will allow you to revalidate the data whenever a specific action occurs, such as after creating or updating a post.

Here's how you can modify your app/admin/page.tsx to include revalidatePath:

  1. Create a Server Action to Revalidate the Path:
    Create a new file app/actions.ts (or any appropriate location) to define a server action that will revalidate the path.

    'use server';
    
    import { revalidatePath } from 'next/cache';
    
    export async function revalidateAdminPage() {
      revalidatePath('/admin');
    }
    
  2. Modify Your Page Component to Use the Server Action:
    Update your app/admin/page.tsx to call the revalidateAdminPage function after fetching data.

    import clientPromise from "../lib/mongodb";
    import { revalidateAdminPage } from "../actions";
    
    interface UserData {
      _id: string;
      name: string;
      email: string;
    }
    
    async function getData() {
      const client = await clientPromise;
      const db = client.db("test");
      const databaseUsers = await db.collection("users").find({}).toArray();
      return databaseUsers;
    }
    
    export default async function Page() {
      const users: UserData[] = await getData();
    
      // Revalidate the path after fetching data
      await revalidateAdminPage();
    
      return (
        <div>
          <h1>User List from MongoDB</h1>
          <ul>
            {users.map((user) => (
              <li className="py-2" key={user._id}>
                <p>{user.name}</p>
                <p>{user.email}</p>
                <p>{user.views}</p>
              </li>
            ))}
          </ul>
        </div>
      );
    }
    
#

Explanation:

  • Server Action: The revalidateAdminPage function uses revalidatePath to revalidate the /admin path.
  • Page Component: The Page component calls revalidateAdminPage after fetching data to ensure the path is revalidated.

This approach ensures that your data is revalidated on-demand, allowing you to fetch fresh data whenever necessary.

For more details on revalidating data, you can refer to the Next.js documentation on revalidating data (https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#revalidating-data).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: