Hello,
I have followed the well explained tutorial on how to integrate MongoDB in Next.JS
I have been able to query the DB to get the list of one collection, but I am now struggling to get one document of a collection based on its ID.
import React from "react";
import Head from "next/head";
import clientPromise from "../../lib/mongodb";
import { ObjectId } from "mongodb";
export default function CompanyShow(companyData) {
return (
<div>
{" "}
<h1>{companyData.name}</h1>...
</div>
);
}
export async function getStaticPaths() {
// Return a list of possible value for id
const client = await clientPromise;
const db = client.db("main");
const companies = db.collection("companies");
// here you can filter for certain data entries in your db
// in this case we only want the ids
const data = await companies.find({}, { _id: 1 }).toArray();
client.close();
return {
// no 404 page will be rendered in case an id is entered which doesn't exist
fallback: "blocking",
// dynamcly calculating the routes
paths: data.map((datapoint) => ({
params: {
companyId: datapoint._id.toString(),
},
})),
};
}
export async function getStaticProps({ context }) {
const client = await clientPromise;
const db = client.db("main");
const companies = db.collection("companies");
// Fetch necessary data for the company using params.id
const companyId = context.params.companyId;
// filter the companies for the companyId you get from context.params.companyId;
const selectedCompanyEntry = await companies.findOne({
_id: ObjectId(companyId),
});
client.close();
return {
props: {
companyData: {
id: selectedCompanyEntry._id.toString(),
name: selectedCompanyEntry.name,
},
},
revalidate: 1,
};
}
Right now on that iteration I am getting an error of undefined params.
Would you be as kind as helping me fix that issue please?
Or orienting me towards a new page documentation of MongoDB explaining step by step how to do it?
Thank you!
Hi @Marving_Moreton ,
The query looks correct to me:
const selectedCompanyEntry = await companies.findOne({
_id: ObjectId(companyId),
});
I suspect the issue is with context.params which might be passed wrongly…
Can you share a full error you get and the line that message it?
Thanks
Pavel
Hello @Pavel_Duchovny, thank you for your reply!
Well… I had some evolution to it!
I had a destructuring issue with passing ( {context}) instead of (contex†).
However, now I am getting a new error: BSONTypeError: Argument passed in must be a string of 12 bytes or a string of 24 hex characters or an integer
It seems that const companyId does not get the _id but the whole object as a whole:
import React from "react";
import Head from "next/head";
import clientPromise from "../../lib/mongodb";
import { ObjectId } from "mongodb";
export default function CompanyShow(props) {
return (
<div>
<h1>{props.companyData.name}</h1>...
</div>
);
}
export async function getStaticPaths() {
// Return a list of possible value for id
const client = await clientPromise;
const db = client.db("main");
const companies = db.collection("companies");
// here you can filter for certain data entries in your db
// in this case we only want the ids
const data = await companies.find({}, { _id: 1 }).toArray();
client.close();
return {
// no 404 page will be rendered in case an id is entered which doesn't exist
fallback: "blocking",
// dynamcly calculating the routes
paths: data.map((datapoint) => ({
params: {
companyId: datapoint._id.toString(),
},
})),
};
}
export async function getStaticProps(context) {
const client = await clientPromise;
const db = client.db("main");
const companies = db.collection("companies");
// Fetch necessary data for the company using params.id
// const companyId = context.params.companyId;
console.log(context.params.companyId);
// console.log(ObjectId(params.companyId));
const companyId = context.params.companyId;
// filter the companies for the companyId you get from context.params.companyId;
const selectedCompanyEntry = await companies.findOne({
_id: ObjectId(companyId),
});
client.close();
return {
props: {
companyData: {
id: selectedCompanyEntry._id.toString(),
name: selectedCompanyEntry.name,
},
},
revalidate: 1000,
};
}
Hi @Marving_Moreton ,
So it looks like the value of companyId
is. not a valid string containing an actual ObjectId format.
Please debug your code and verify that the string you provide is constructed to be converted to an objectId…
Thank
Pavel
2 Likes
Yeah I have figured my error.
I were looking to have the [slug] as URL and not the Id itself
1 Like