如何添加到mongodb,MERN应用验证失败错误

时间:2019-03-03 13:32:05

标签: reactjs api redux mern

我正在尝试学习MERN堆栈,我正在尝试创建一个简单的购物清单应用。

我有一个简单的api来获取,发布和删除项目,这在测试api时都可以使用Postman进行。

在本地获取作品,我可以从数据库中获取项目。

当我尝试添加到数据库时,出现此错误。

(node:28550) UnhandledPromiseRejectionWarning: ValidationError: item validation failed: name: Path `name` is required.
[0]     at new ValidationError (/Users/user/Documents/_Work/cd/MERN/merntest-redux-1/node_modules/mongoose/lib/error/validation.js:30:11)
[0]     at model.Document.invalidate (/Users/user/Documents/_Work/cd/MERN/merntest-redux-1/node_modules/mongoose/lib/document.js:2080:32)
[0]     at p.doValidate.skipSchemaValidators (/Users/user/Documents/_Work/cd/MERN/merntest-redux-1/node_modules/mongoose/lib/document.js:1943:17)
[0]     at /Users/user/Documents/_Work/cd/MERN/merntest-redux-1/node_modules/mongoose/lib/schematype.js:933:9
[0]     at _combinedTickCallback (internal/process/next_tick.js:131:7)
[0]     at process._tickCallback (internal/process/next_tick.js:180:9)
[0] (node:28550) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
[0] (node:28550) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

由于api在邮递员中工作,我认为这一定是我正在使用的redux的事情。

ShoppingList js

import React, {Component} from 'react';
import uuid from 'uuid';
import {connect} from 'react-redux';
import {getItems, deleteItem, addItem} from '../actions/itemActions';

class ShoppingList extends Component{

  componentDidMount(){
    this.props.getItems()
  }

  onDeleteClick = (id) => {
    this.props.deleteItem(id);
  }

  render(){

    const {items} = this.props.item

    return(
      <div>
        <button
          onClick={() => {
            const name = prompt('New Item')

            if(name){
              this.props.addItem(name)
            }
          }}
        >
          Add Item
        </button>
        <ul>
          {items.map(({id,name}) =>{
            return(
              <li key={id}>
                <button
                  onClick={this.onDeleteClick.bind(this, id)}
                >
                  &times;
                </button>
                {name}
              </li>
            )
          })}
        </ul>
      </div>
    )
  }

}

const mapStateToProps = state => ({
  item: state.item
})

export default connect (mapStateToProps, {getItems, deleteItem, addItem})(ShoppingList)

itemActions

import axios from 'axios';
import {GET_ITEMS, ADD_ITEM, DELETE_ITEM, ITEMS_LOADING} from '../actions/types';

export const getItems = () => dispatch =>{
  dispatch(setItemsLaoding());
  axios
    .get('/api/items')
    .then(res => 
      dispatch({
        type: GET_ITEMS,
        payload: res.data
      })
    )
}

export const addItem = (name) => dispatch =>{
  axios 
    .post('/api/items', name)
    .then(res => 
      dispatch({
        type: ADD_ITEM,
        payload: res.data
      })
    )
}

export const deleteItem = (id) =>{
  return{
    type: DELETE_ITEM,
    payload: id
  }
}

export const setItemsLaoding = () => {
  return{
    type: ITEMS_LOADING
  }
}

itemReducer.js

import {GET_ITEMS, ADD_ITEM, DELETE_ITEM, ITEMS_LOADING} from '../actions/types';

const initialState = {
  items: [],
  loading: false
}

export default function(state = initialState, action){
  switch(action.type){
    case GET_ITEMS:
      return{
        ...state,
        items: action.payload,
        loading:false
      }
    case DELETE_ITEM:
      return{
        ...state,
        items: state.items.filter(item => item.id !== action.payload)
      }  
    case ADD_ITEM:
      return{
        ...state,
        items: [...state.items, { name: action.payload}]
      }  
    case ITEMS_LOADING:
      return{
        ...state,
        loading:true
      }
    default:
      return state  
  }
}

models / Item.js(猫鼬模型)

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const ItemSchema = new Schema({
  name:{
    type: 'String',
    required: true 
  },
  Date:{
    type: Date,
    default: Date.now
  }
})

module.exports = Item = mongoose.model('item', ItemSchema); 

routes / api / items.js

const express = require('express');
const router = express.Router();

const Item = require('../../models/Item');

router.get('/', (req, res) => {
    Item.find()
        .then(items => res.json(items))
        .catch(err => console.log(err))
});

router.post('/', (req, res) => {
    const newItem = new Item({
        name: req.body.name
    })
    newItem
        .save()
        .then(item => res.json(item))
        .catch(err => console.log(err))
})

router.delete('/:id', (req, res) =>{
    Item.findById(req.params.id)
        .then(item => item.remove().then(() => res.json({success:true})))
        .catch(err => err.status(404).json({success:false}))
})

module.exports = router;

2 个答案:

答案 0 :(得分:0)

好的,我进行了一些调试,这就是问题所在,您将项目名称作为键发送,没有任何值,因此API无法理解。

更改此代码:

export const addItem = (name) => dispatch =>{
  axios 
    .post('/api/items', name)
    .then(res => 
      dispatch({
        type: ADD_ITEM,
        payload: res.data
      })
    )
}

此代码:

export const addItem = name => dispatch => {
  const req = {
    name,
  };

  axios.post('/api/items', req).then(res =>
    dispatch({
      type: ADD_ITEM,
      payload: res.data,
    })
  );
};

答案 1 :(得分:0)

我通过将这段代码添加到routes/api/items.js中来解决了这个问题:

var bodyParser = require("body-parser");

router.use(bodyParser.json());
router.use(bodyParser.urlencoded({ extended: true }));