英文:
How to get dynamic segment in Next.js 13 app router?
问题
我想从Next.js 13使用API Router和MongoDB作为我的数据库来获取数据。目前,我正在使用新的App Router。
当我从集合中获取所有数据时,成功了,但是当我想要获取单个数据时,失败了。
错误信息如下:
TypeError: Cannot read properties of undefined (reading 'id')
at GET (webpack-internal:///(sc_server)/./app/api/shop/[id]/route.tsx:14:30)
// 更多错误信息...
以下是我的代码
/app/api/shop/[id]/route.tsx
import { connectToDatabase } from "@/lib/mongo";
import { NextRequest, NextResponse } from "next/server";
import { ObjectId } from "mongodb";
export async function GET(req: NextRequest, res: NextResponse) {
try {
const id = req.query.id;
const client = await connectToDatabase();
const db = client.db("MyShopDB");
const oneProduct = await db.collection("Products").findOne({ _id: ObjectId(id) });
if (oneProduct)
return NextResponse.json(oneProduct);
else
return res.status(404).json({ message: "Products Not Found" });
} catch (error) {
console.log(error);
return new Response("Failed to fetch all prompts", { status: 500 });
}
}
以下是获取所有产品的代码
/app/api/shop/route.tsx
import { connectToDatabase } from "@/lib/mongo";
import { NextRequest, NextResponse } from "next/server";
export async function GET(req: NextRequest, res: NextResponse) {
try {
const client = await connectToDatabase();
const db = client.db("MyShopDB");
const allProducts = await db.collection("Products").find().toArray();
return NextResponse.json(allProducts);
} catch (error) {
return new Response("Failed to fetch all prompts", { status: 500 });
}
}
希望以上翻译对你有帮助。如果有任何问题,请随时提出。
英文:
I want to fetch a data using API Router from Next.js 13 using MongoDB as my DBMS. Currently, I'm using the new App Router.
When I'm fetching all data from a collection it succeeded, but when I want to fetch only one data, it fails.
The error says
TypeError: Cannot read properties of undefined (reading 'id')
at GET (webpack-internal:///(sc_server)/./app/api/shop/[id]/route.tsx:14:30)
at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:265:43)
at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/lib/trace/tracer.js:111:36)
at NoopContextManager.with (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:360:30)
at ContextAPI.with (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:30:58)
at NoopTracer.startActiveSpan (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:953:34)
at ProxyTracer.startActiveSpan (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:993:36)
at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/lib/trace/tracer.js:100:107)
at NoopContextManager.with (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:360:30)
at ContextAPI.with (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:30:58)
at NextTracerImpl.trace (webpack-internal:///(sc_server)/./node_modules/next/dist/server/lib/trace/tracer.js:100:32)
at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:253:53)
at AsyncLocalStorage.run (node:async_hooks:330:14)
at Object.wrap (webpack-internal:///(sc_server)/./node_modules/next/dist/server/async-storage/static-generation-async-storage-wrapper.js:41:24)
at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:207:97)
at AsyncLocalStorage.run (node:async_hooks:330:14)
at Object.wrap (webpack-internal:///(sc_server)/./node_modules/next/dist/server/async-storage/request-async-storage-wrapper.js:77:24)
at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:206:75)
at AsyncLocalStorage.run (node:async_hooks:330:14)
at AppRouteRouteModule.execute (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:203:56)
at AppRouteRouteModule.handle (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:326:41)
at RouteHandlerManager.handle (D:\Projects\MyShop\node_modules\next\dist\server\future\route-handler-managers\route-handler-manager.js:28:29)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async doRender (D:\Projects\MyShop\node_modules\next\dist\server\base-server.js:996:38)
at async cacheEntry.responseCache.get.incrementalCache.incrementalCache (D:\Projects\MyShop\node_modules\next\dist\server\base-server.js:1172:40)
at async D:\Projects\MyShop\node_modules\next\dist\server\response-cache\index.js:99:36
Here is my code
/app/api/shop/[id]/route.tsx
import { connectToDatabase } from "@/lib/mongo";
import { NextRequest, NextResponse } from "next/server";
import { ObjectId } from "mongodb";
export async function GET (req : NextRequest, res : NextResponse) {
try {
const id = req.query.id;
const client = await connectToDatabase();
const db = client.db("MyShopDB");
// console.log(req);
const oneProduct = await db.collection("Products").findOne({ _id: ObjectId(id) });
// return new Response(JSON.stringify(allProducts), { status: 200 });
if(oneProduct)
return NextResponse.json(oneProduct)
else
return res.status(404).json({message: "Products Not Found"})
} catch (error) {
console.log(error);
return new Response("Failed to fetch all prompts", { status: 500 })
}
}
Here is code for fetching all products
/app/api/shop/route.tsx
import { connectToDatabase } from "@/lib/mongo";
import { NextRequest, NextResponse } from "next/server";
export async function GET (req: NextRequest, res: NextResponse) {
try {
const client = await connectToDatabase();
const db = client.db("MyShopDB");
console.log(req);
const allProducts = await db.collection("Products").find().toArray();
// return new Response(JSON.stringify(allProducts), { status: 200 });
return NextResponse.json(allProducts);
} catch (error) {
return new Response("Failed to fetch all prompts", { status: 500 })
}
}
答案1
得分: 1
错误很可能是由对req.query.id
的访问引起的,这在app
文件夹中的动态API路由中是无效的。
当在app
目录中使用具有动态段的路由处理程序时,可以从函数的第二个参数中的params
属性中访问动态参数。
// `/app/api/shop/[id]/route.tsx`
import { type NextRequest } from 'next/server';
export async function GET(request: Request, { params }: { params: { id: string } }) {
const id = params.id;
console.log(id);
// 其余的API函数
}
有关更多详细信息,请参阅路由处理程序,动态路由段文档。
英文:
The error is most likely caused by the access to req.query.id
, which is not valid for a dynamic API route in the app
folder.
When using a route handler with dynamic segments inside the app
directory, the dynamic parameter can be accessed from the params
property in the function's second parameter.
// `/app/api/shop/[id]/route.tsx`
import { type NextRequest } from 'next/server';
export async function GET(request: Request, { params }: { params: { id: string } }) {
const id = params.id;
console.log(id);
// Rest of your API function
}
For more details see Route Handlers, Dynamic Route Segments documentation.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论