Now extend the fetching from MongoDB to

  • Individual page (dynamic page) of next.
  • On the same dynamic page, the URLs also we will get from the DB (GSPa)

Both of these to be done in dynamic page [ ]

fetching URLs for GSPa

export async function getStaticPaths() {
  const uri = `mongodb+srv://${secret.user}:${secret.pass}@cluster0.xf7jy.mongodb.net/myFirstDB?retryWrites=true&w=majority`;
  const client = await MongoClient.connect(uri);
  const db = client.db();
  const notesCollection = db.collection("notesColl2");

  const notesIds = await notesCollection.find({}, { _id: 1 }).toArray();

  client.close();

  //test: preparing the material needed to be returned from GSPa
  console.log(
    notesIds.map((item) => ({
      params: {
        noteId: item._id.toString(),
      },
    }))
  );

  return {
    fallback: false,
    paths: notesIds.map((item) => ({
      params: {
        noteId: item._id.toString(),
      },
    })),

    // paths should be something like this:
    // [
    //   {
    //     params: {
    //       noteId: "n1",
    //     },
    //   },
    //   {
    //     params: {
    //       noteId: "n2",
    //     },
    //   },
    // ],
  };
}

Fetch data for individual page

export async function getStaticProps(context) {
  // way to get slug from URL in GSP - square bracket is key
  const noteId = context.params.noteId;
  console.log(`Loading ID: ${noteId}`);

  // fetch data for a single note.
  const uri = `mongodb+srv://${secret.user}:${secret.pass}@cluster0.xf7jy.mongodb.net/myFirstDB?retryWrites=true&w=majority`;
  const client = await MongoClient.connect(uri);
  const db = client.db();
  const notesCollection = db.collection("notesColl2");

  const selectedNote = await notesCollection.findOne({ _id: ObjectId(noteId) });

  client.close();

  return {
    props: {
      noteData: {
        id: selectedNote._id.toString(),
        title: selectedNote.title,
        image: selectedNote.image,
        address: selectedNote.address,
        description: selectedNote.description,
      },
    },
  };
}

Need to import ObjectId from mongodb because when doing find for a single page, we have string ID and the DB has Object for ID. To make them equal before comparing in findOne, wrap your string URL with ObjectId()

import { MongoClient, ObjectId } from "mongodb";

const selectedNote = await notesCollection.findOne({ _id: ObjectId(noteId) });

Final Code for dynamic page:

import NoteDetail from "../../components/notes/NoteDetail";
import secret from "../../secure/secrets";
import { MongoClient, ObjectId } from "mongodb";

function NoteDetails(props) {
  return (
    <NoteDetail
      noteId={props.noteData.id}
      title={props.noteData.title}
      address={props.noteData.address}
      image={props.noteData.image}
      description={props.noteData.description}
    ></NoteDetail>
  );
}

export async function getStaticPaths() {
  const uri = `mongodb+srv://${secret.user}:${secret.pass}@cluster0.xf7jy.mongodb.net/myFirstDB?retryWrites=true&w=majority`;
  const client = await MongoClient.connect(uri);
  const db = client.db();
  const notesCollection = db.collection("notesColl2");

  const notesIds = await notesCollection.find({}, { _id: 1 }).toArray();

  client.close();

  //test: preparing the material needed to be returned from GSPa
  console.log(
    notesIds.map((item) => ({
      params: {
        noteId: item._id.toString(),
      },
    }))
  );

  return {
    fallback: false,
    paths: notesIds.map((item) => ({
      params: {
        noteId: item._id.toString(),
      },
    })),
  };
}

export async function getStaticProps(context) {
  // way to get slug from URL in GSP - square bracket is key
  const noteId = context.params.noteId;
  console.log(`Loading ID: ${noteId}`);

  // fetch data for a single note.
  const uri = `mongodb+srv://${secret.user}:${secret.pass}@cluster0.xf7jy.mongodb.net/myFirstDB?retryWrites=true&w=majority`;
  const client = await MongoClient.connect(uri);
  const db = client.db();
  const notesCollection = db.collection("notesColl2");

  const selectedNote = await notesCollection.findOne({ _id: ObjectId(noteId) });

  client.close();

  return {
    props: {
      noteData: {
        id: selectedNote._id.toString(),
        title: selectedNote.title,
        image: selectedNote.image,
        address: selectedNote.address,
        description: selectedNote.description,
      },
    },
  };
}

export default NoteDetails;