我无法使用 mongoose 在 mongoDB 服务器中创建文档?

问题描述 投票:0回答:1

我无法在本地部署的 mongodb 服务器中使用 mongoose 正确创建文档。仅创建 id,而不是我发送的完整数据(姓名、电子邮件、密码)。在服务器中,数据看起来像这样

{ "_id": { "$oid": "651d8f91c018db3d9504da2a" }, "__v": 0 }
Mongosh shell 和 MongoDB 指南针工作正常。但是 mongosh shell 给出了这个警告:
 Access control is not enabled for the database.
。我不知道这是否是一个问题。

架构:

const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
    name : {type: String , 
        required: true 
    },
    email : {type: String ,
        required: true 
       },
    password : {type: String ,
         required: true 
        },
}, {timestamps: true});

module.exports = mongoose.model('user', userSchema);

HTML:

<div class="loginform">
      <div class="login">
        <label for="name">Name</label><input type="text" id="name" />
      </div>
      <div class="login">
        <label for="email">Email</label><input type="text" id="email" />
      </div>
      <div class="login">
        <label for="password">Password</label
        ><input type="text" id="password" />
        <button id="signinbutton">Create Account</button>
      </div>
    </div>

在前面发帖请求

async function postData(url = "", data = {}) {
        const response = await fetch(url, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify(data),
        });
        let rdata = await response.json()
        return rdata
      };

      let submit = document.getElementById("signinbutton")
      submit.addEventListener("click", async() => {
        let name = document.getElementById("name").value
        let email = document.getElementById("email").value
        let password = document.getElementById("password").value
        let resp= await  postData("/signin", { name, email, password })
        if(resp.success){
            alert("user created")
        }
       })

发帖请求

const express = require('express');
const app = express();
const path = require('path');
const mongoose = require('mongoose');
var bodyParser = require('body-parser')
const postm = require('./models/post');
const User =  require('./models/User');
mongoose.connect('mongodb://127.0.0.1/blogbase');
app.use(express.json({extended:true}));
app.use(express.urlencoded({extended: true}));
app.use(express.static(path.join(__dirname, "static")));
 const port = 3000
 app.listen(port, () =>{
  console.log('app http://localhost:${port}')
});

 app.post('/signin', async(res,req) => {
  let user = await User.create(req.body)
  console.log(req.body)
  res.status(200).json({success: true, user: user })
});

错误

D:\webdevedu\LBLOG\node_modules\mongoose\lib\document.js:3166
    this.$__.validationError = new ValidationError(this);
                               ^

ValidationError: user validation failed: password: Path `password` is required., email: Path `email` is required., name: Path `name` is required.
    at Document.invalidate (D:\webdevedu\LBLOG\node_modules\mongoose\lib\document.js:3166:32)
    at D:\webdevedu\LBLOG\node_modules\mongoose\lib\document.js:2959:17
    at D:\webdevedu\LBLOG\node_modules\mongoose\lib\schematype.js:1368:9
    at process.processTicksAndRejections (node:internal/process/task_queues:77:11) {
  errors: {
    password: ValidatorError: Path `password` is required.
        at validate (D:\webdevedu\LBLOG\node_modules\mongoose\lib\schematype.js:1365:13)
        at SchemaType.doValidate (D:\webdevedu\LBLOG\node_modules\mongoose\lib\schematype.js:1349:7)
        at D:\webdevedu\LBLOG\node_modules\mongoose\lib\document.js:2951:18
        at process.processTicksAndRejections (node:internal/process/task_queues:77:11) {
      properties: {
        validator: [Function (anonymous)],
        message: 'Path `password` is required.',
        type: 'required',
        path: 'password',
        value: undefined
      },
      kind: 'required',
      path: 'password',
      value: undefined,
      reason: undefined,
      [Symbol(mongoose:validatorError)]: true
    },
    email: ValidatorError: Path `email` is required.
        at validate (D:\webdevedu\LBLOG\node_modules\mongoose\lib\schematype.js:1365:13)
        at SchemaType.doValidate (D:\webdevedu\LBLOG\node_modules\mongoose\lib\schematype.js:1349:7)
        at D:\webdevedu\LBLOG\node_modules\mongoose\lib\document.js:2951:18
        at process.processTicksAndRejections (node:internal/process/task_queues:77:11) {
      properties: {
        validator: [Function (anonymous)],
        message: 'Path `email` is required.',
        type: 'required',
        path: 'email',
        value: undefined
      },
      kind: 'required',
      path: 'email',
      value: undefined,
      reason: undefined,
      [Symbol(mongoose:validatorError)]: true
    },
    name: ValidatorError: Path `name` is required.
        at validate (D:\webdevedu\LBLOG\node_modules\mongoose\lib\schematype.js:1365:13)
        at SchemaType.doValidate (D:\webdevedu\LBLOG\node_modules\mongoose\lib\schematype.js:1349:7)
        at D:\webdevedu\LBLOG\node_modules\mongoose\lib\document.js:2951:18
        at process.processTicksAndRejections (node:internal/process/task_queues:77:11) {
      properties: {
        validator: [Function (anonymous)],
        message: 'Path `name` is required.',
        type: 'required',
        path: 'name',
        value: undefined
      },
      kind: 'required',
      path: 'name',
      value: undefined,
      reason: undefined,
      [Symbol(mongoose:validatorError)]: true
    }
  },
  _message: 'user validation failed'
}

Node.js v18.17.0
[nodemon] app crashed - waiting for file changes before starting...

mongodb mongoose mongoose-schema mongodb-shell mongoose-models
1个回答
0
投票

当您的猫鼬模型尝试创建新用户时,

email
name
password
的值未定义。您的代码存在一些问题导致此问题,但看起来值没有被发送。

首先,如果您要提交表单数据,那么实际使用表单更具语义性。我可以看到您正在使用 JS 通过

id
来获取元素,但是
<form>
元素已经提供了一种访问每种类型输入的便捷方法,因此只需为每个输入提供一个 name 属性即可。我会解释。像这样更新你的 HTML:

<form name="loginform" action="/signin">
   <div class="login">
      <label for="name">Name</label>
      <input type="text" id="name" name="name">
   </div>
   <div class="login">
      <label for="email">Email</label>
      <input type="text" id="email" name="email">
   </div>
   <div class="login">
      <label for="password">Password</label>
      <input type="text" id="password" name="password">
      <button id="signinbutton">Create Account</button>
   </div>
</form>

接下来,将

addEventListener
绑定到实际表单并阻止其自动提交的默认行为。您也没有对获取网络请求进行错误处理,因此您不知道表单是否正确发送。像这样更新:

const form = document.querySelector('form[name="loginform"]')
form.addEventListener('submit', (e)=>{
   e.preventDefault(); //< Prevent the form from submitting
   let name = form.elements.name; //< Get each input element
   let email = form.elements.email;
   let password = form.elements.password;
 
   fetch(form.action, { //< Now run fetch using form.action as url
      method: 'POST',
      body: JSON.stringify({ name, email, password }),
      headers: {
       'Content-type': 'application/json; charset=UTF-8',
      }
   })
   .then((response)=>{ 
      return response.json();
   })
   .then((data)=>{
      console.log(data);
      //Now handle a successful user creation 
   })
   .catch(error => {
      console.error('Error:', error)
      //Now handle an unsuccessful user creation 
   });
});

您在服务器上的发布路由看起来不错,但您再次需要能够捕获任何错误。我建议像这样使用

try/catch
并在错误时向客户端发送适当的响应:

app.post('/signin', async(res,req) => {
   console.log(req.body); //< Make sure the form data has been parsed in req.body
   try{
      const {name, email, password} = req.body; //< Destructure only the values you need
      let user = await User.create({name, email, password});
      res.status(200).json({success: true, user: user });
   }catch(err){
      console.log(err);
      res.status(400).json({success: false, err: 'Appropriate error message' });
   }
});

希望这对您有帮助,祝您的项目好运。

© www.soinside.com 2019 - 2024. All rights reserved.