首页 > 解决方案 > MERN 堆栈:值“NaN”的数字转换失败

问题描述

我正在创建一个简单的用户注册页面,当我通过 axios 发布请求时,帐户级别(1 = 用户和 2 = 管理员)会出错。这似乎是一个比较常见的错误,主要是通过在模式中使用默认数字值来纠正的,我已经拥有了。此外,当我使用邮递员进行测试时,我没有遇到此错误。

错误:

Error: users validation failed: accLevel: Cast to Number failed for value "NaN" (type number) at path "accLevel", username: Path `username` is required., password: Path `password` is required.
    at ValidationError.inspect (E:\SLIIT\Y2S2\ITP\FitnessFactory\backend\node_modules\mongoose\lib\error\validation.js:48:26)

但是,当我使用邮递员进行测试时,我没有收到此错误并且 mongodb 可以正常工作。像这样。它也适用于 int 形式的 accLevel。

{
    "username": "Mary",
    "password": "mary",
    "accType": "customer",
    "accLevel": "1"
}

这是用户模式

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const userSchema = new Schema({

    username : {
        type: String,
        required: true
    },

    password : {
        type: String,
        required: true
    },

    accType: {
        enum: ["customer", "instructor"],
        //required: true
    },

    accLevel: {
        type: Number,
        default: 1
    }
})

const User = mongoose.model('users', userSchema);

module.exports = User;

这是用户路由和控制器文件

const router = require("express").Router();
let User = require("../models/user");

//createUserAccount
router.route("/createUserAccount").post((req,res) => {

    const username = req.body.username;
    const password = req.body.password;
    const accType = req.body.accType;
    const accLevel = Number(req.body.accLevel);

    const newUser = new User({
        username,
        password,
        accType,
        accLevel
    })

    newUser.save().then(() => {
    res.json("User account created")
    }).catch((err) => {
        console.log(err);
    })
})


//login
router.route("/userLogin/:id").post(async(req,res) => {
    
})



module.exports = router;

这是 createUserAccount.jsx 的组件文件

//Create account component
import React, {useState} from "react";
import axios from 'axios';

//bootstrap imports
import Form from 'react-bootstrap/Form';
import Button from "react-bootstrap/Button";
import Container from 'react-bootstrap/Container';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
//custom styles
import '../styles/CreateAccount.css';

function CreateAccount(){
    //set states
    const [username, setUsername] = useState("");
    const [password, setPassword] = useState("");
    const [reEnterPassword, setReEnterPassword] = useState("");
    const [accType, setAccType] = useState("");
    const [accLevel, setAccLevel] = useState("");

    //handle change
    function handleSubmit(e){
        e.preventDefault();

        if (password !== reEnterPassword){
            alert("Passwords do not match!")
        }
        else if (accType === ''){
            alert("Select account type!")
        }
        else if (accLevel === ''){
            alert("Select account level!")
        }
        else{
            const newUser = {
                username,
                password,
                accType,
                accLevel
            }
    
            console.log(newUser);

            axios.post("http://localhost:8070/user/createUserAccount").then(()=>{
                alert("account created")
            }).catch((err)=>{
                alert(err)
            })
        }
    }

    return (
        <div>
            <div className='createAccountBlock'>
                <h1>Create Account</h1>

                <form onSubmit={handleSubmit}>
                    <Form.Group name="username" className="mb-3" controlId="username">
                        <Form.Label>Username</Form.Label>
                        <Form.Control type="text" placeholder="Enter Username" className='formText'
                        onChange = {(e)=>{
                            setUsername(e.target.value);
                        }}
                        />
                    </Form.Group>

                    <Form.Group name="password" className="mb-3" controlId="password">
                        <Form.Label>Password</Form.Label>
                        <Form.Control type="password" placeholder="Password" className='formText'
                        onChange = {(e)=>{
                            setPassword(e.target.value);
                        }}
                        />
                    </Form.Group>

                    <Form.Group name="reEnterPassword" className="mb-3" controlId="reEnterPassword">
                        <Form.Label>Re-enter Password</Form.Label>
                        <Form.Control type="password" placeholder="Re-enter Password" className='formText'
                        onChange = {(e)=>{
                            setReEnterPassword(e.target.value);
                        }}
                        />
                    </Form.Group>

                    <Container>
                        <Row>
                            <Col>
                                <Form.Select name="accType" aria-label="Default select example" 
                                onChange = {(e)=>{
                                    setAccType(e.target.value);
                                }}
                                >
                                    <option>Select Account Type</option>
                                    <option value="customer">Customer</option>
                                    <option value="instructor">Instructor</option>
                                </Form.Select>
                            </Col>
                            <Col>
                                <Form.Select name="accLevel" aria-label="Default select example" 
                                onChange = {(e)=>{
                                    setAccLevel(e.target.value);
                                }}
                                >
                                    <option>Select Account Level</option>
                                    <option value="1">Level 1 (user)</option>
                                    <option value="2">Level 2 (admin)</option>
                                </Form.Select>
                            </Col>
                        </Row>

                        <div className='flex-container'>
                            <Button variant="primary" type="submit" className='btn1'>
                                Create Account
                            </Button>
                        </div>
                    </Container>
                </form>
            </div>
        </div>
    );
}

export default CreateAccount;

当我使用 postman 测试 int 和 string 时,它可以工作,但使用 axios 失败。顺便说一句,我也从前端尝试了 parseInt 。

有任何想法吗?

标签: node.jsreactjsmongoose

解决方案


您似乎没有在 POST 请求中发送数据对象。

axios.post("http://localhost:8070/user/createUserAccount").then(()=>{
            alert("account created")
        }).catch((err)=>{
            alert(err)
        })

axios.post 需要您发送的对象的第二个参数。


推荐阅读