TypeError:无法读取undefined的属性(阅读'json')
嗨,我正在使用TypeScript和node/Next.js 13以及新的应用程序路由器和mongoose将数据推送到Mongo数据库中,但它一直向我发送这个错误:“类型错误:无法读取undefined的属性(阅读'json')"。有效负载显示在浏览器的Network部分,但不会传递到数据库。我是Next.js和TypeScript的新手,所以如果我错过了一些明显的东西,我很抱歉,但我非常绝望,我已经尝试了许多解决方案,没有一个有帮助。提前谢谢!
创建新产品时尝试将数据传递到数据库。
product/new/page.tsx
"use client"
import Plan from "@/app/components/Plan";
import axios from "axios";
import { useState } from "react";
export default function NewProduct() {
const [title, setTitle] = useState('');
const [description, setDescription] = useState('');
const [price, setPrice] = useState('');
async function createProduct(ev:any) {
ev.preventDefault();
await axios.post('../../api/products', {title, description, price});
}
return (
<Plan>
<div className="max-w-md mx-auto mt-14">
<h2 className="text-2xl font-bold mb-4">Pievienot jaunu preci</h2>
<form onSubmit={ createProduct }>
<div className="mb-4">
<label htmlFor="productName" className="block text-gray-700 text-sm font-bold mb-2">
Preces nosaukums:
</label>
<input
type="text"
className="appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
placeholder="Ievadiet preces nosaukumu"
value={title}
onChange={ev => setTitle(ev.target.value)}
/>
</div>
<div className="mb-4">
<label htmlFor="description" className="block text-gray-700 text-sm font-bold mb-2">
Apraksts:
</label>
<textarea
className="appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
placeholder="Ievadiet preces aprakstu"
value={description}
onChange={ev => setDescription(ev.target.value)}
/>
</div>
<div className="mb-4">
<label htmlFor="price" className="block text-gray-700 text-sm font-bold mb-2">
Cena:
</label>
<input
type="text"
className="appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
placeholder="Ievadiet preces cenu"
value={price}
onChange={ev => setPrice(ev.target.value)}
/>
</div>
<div className="flex items-center justify-end">
<button
type="submit"
className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline">
Pievienot
</button>
</div>
</form>
</div>
</Plan>
)
}
src/app/API/products/page.ts
import { NextApiRequest, NextApiResponse } from "next";
import { NextResponse } from "next/server";
import { mongooseConnect } from "../../../../lib/mongoose";
import { Product } from "../../../../models/Product";
export default async function handle(req: NextApiRequest, res: NextApiResponse) {
const { method } = req;
await mongooseConnect();
console.log({res})
console.log({req})
const { title, description, price } = req.body || {};
const productDoc = await Product.create({
title,
description,
price,
});
const data = res.json(productDoc);
return NextResponse.json(data);
}
调试res.json时,Console返回:{ res: undefined } { req: { params: {}, searchParams: {} } }
models/Product.ts
import mongoose, { Schema } from "mongoose";
const ProductSchema = new Schema({
title: String,
description: String,
price: Number,
});
export const Product = mongoose.models.Product || mongoose.model('Product', ProductSchema);
lib/mongoose.ts
import mongoose from "mongoose";
export function mongooseConnect() {
const uri = process.env.MONGODB_URI;
if (mongoose.connection.readyState === 1) {
return Promise.resolve(mongoose.connection);
} else {
return mongoose.connect(uri!);
}
}
lib/mongodb.ts
// This approach is taken from https://github.com/vercel/next.js/tree/canary/examples/with-mongodb
import { MongoClient } from "mongodb";
if (!process.env.MONGODB_URI) {
throw new Error('Invalid/Missing environment variable: "MONGODB_URI"');
}
const uri = process.env.MONGODB_URI;
const options = {};
let client;
let clientPromise: Promise<MongoClient>;
if (process.env.NODE_ENV === "development") {
// In development mode, use a global variable so that the value
// is preserved across module reloads caused by HMR (Hot Module Replacement).
if (!global._mongoClientPromise) {
client = new MongoClient(uri, options);
global._mongoClientPromise = client.connect();
}
clientPromise = global._mongoClientPromise;
} else {
// In production mode, it's best to not use a global variable.
client = new MongoClient(uri, options);
clientPromise = client.connect();
}
// Export a module-scoped MongoClient promise. By doing this in a
// separate module, the client can be shared across functions.
export default clientPromise;
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "models/Product.js", "src/app/api/products/page.js", "src/app/api/products.js"],
"exclude": ["node_modules"]
}
1条答案
按热度按时间sf6xfgos1#
你的API
handle
函数失败了。