简体   繁体   中英

Posting to mongoDB in react with redux/redux-thunk

Mock Library Displays books (author title genre) from the database and the ability to add a book.

The data is being properly acquired from my react component.
The data is being passed in kind to my action creator and likewise is being handled correctly by the reducer.
It would seem as if my async thunk is properly set up to make the post request with axios. I am properly fetching the books already in the database with a get request.

My routes appear to be working as I am able to properly add a book and fetch all books using postman. And again, my books are displaying properly when fetched from my react component.

Where is the issue coming in? Why is my post request not reaching my database?

My actions--

export const fetchBooks = () => dispatch => {
    axios.get('/books')
        .then(res => dispatch({
            type: FETCH_BOOKS,
            payload: res.data
        })) 
}

export const addBook = ({ title, author, genre}) => dispatch => {
    dispatch(addBookStarted())
    axios
      .post('/books', {
        title, 
        author, 
        genre
      })
      .then(res => {
        dispatch(addBookSuccess(res.data))
      })
      .catch(err => {
          dispatch(addBookFailure(err.message))
      })
}


const addBookSuccess = book => ({
    type: ADD_BOOK_SUCCESS,
    payload: {
      ...book
    }
});

const addBookStarted = () => ({
    type: ADD_BOOK_STARTED
});

My reducer --

const initialState = {
    books: [],
    error: null,
    loadinng: false
}

export default function(state = initialState, action) {
    switch(action.type) {
        case FETCH_BOOKS:
            return {
                ...state,
                books: action.payload
            }

        case ADD_BOOK_STARTED:
            return {
                ...state,
                loading: true
            }

        case ADD_BOOK_SUCCESS:
            return {
                ...state,
                loading: false,
                error: null,
                books: [...state.books, action.payload]
            }

        case ADD_BOOK_FAILURE:
            return {
                ...state,
                loading: false,
                error: action.payload.error
            }

        default: 
            return state
    }
}

Error--

{ ValidationError: book validation failed: title: Path `title` is required., aut
hor: Path `author` is required., genre: Path `genre` is required.
    at ValidationError.inspect (C:\Users\Leeko\documents\repos\libapp\backend\no
de_modules\mongoose\lib\error\validation.js:59:24)
    at formatValue (internal/util/inspect.js:526:31)
    at inspect (internal/util/inspect.js:194:10)
    at Object.formatWithOptions (util.js:90:12)
    at Console.(anonymous function) (console.js:204:15)
    at Console.warn (console.js:221:31)
    at b.save.then.catch.err (C:\Users\Leeko\documents\repos\libapp\backend\serv
er.js:34:31)
    at process.internalTickCallback (internal/process/next_tick.js:77:7)
  errors:
   { title:
      { ValidatorError: Path `title` is required.
          at new ValidatorError (C:\Users\Leeko\documents\repos\libapp\backend\n
ode_modules\mongoose\lib\error\validator.js:29:11)
          at validate (C:\Users\Leeko\documents\repos\libapp\backend\node_module
s\mongoose\lib\schematype.js:926:13)
          at C:\Users\Leeko\documents\repos\libapp\backend\node_modules\mongoose
\lib\schematype.js:979:11
          at Array.forEach (<anonymous>)
          at SchemaString.SchemaType.doValidate (C:\Users\Leeko\documents\repos\
libapp\backend\node_modules\mongoose\lib\schematype.js:935:19)
          at C:\Users\Leeko\documents\repos\libapp\backend\node_modules\mongoose
\lib\document.js:1941:9
          at process.internalTickCallback (internal/process/next_tick.js:70:11)
        message: 'Path `title` is required.',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'required',
        path: 'title',
        value: undefined,
        reason: undefined,
        [Symbol(mongoose:validatorError)]: true },

sever.js (route)

const mongoose    = require("mongoose");
const express     = require("express");
const bodyParser  = require("body-parser");

const db          = require('./config/db');

const Book        = require('./models/book');

const app         = express();

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

app.route('/books')
    .get((req, res) => {
        Book.find({}).then(docs => res.json(docs))
    })
    .post((req, res) => {
        let b = new Book({
            title: req.body.title,
            author: req.body.author,
            genre: req.body.genre
        })

        b.save()
            .then(doc => console.log(doc))
            .catch(err => console.error(err))
        res.json(req.body)
    })

book model

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

const BookSchema = new Schema({
    title: {
        type: String,
        // required: true,
        lowercase: true
    },
    author: {
        type: String,
        // required: true,
        lowercase: true
    },
    genre: {
        type: String,
        // required: true,
        lowercase: true
    },
    pages: {
        type: Number
    },
    available: {
        type: Boolean,
        default: true
    }
});

module.exports = Book = mongoose.model('book', BookSchema);

In my server.js I was missing below:

...
app.use(bodyParser.json());
...

您可能需要在 axios 设置中支持完整的 url HOST,还请发布上下文错误日志

A small change in axios call

axios
      .post('/books', {
        'title':title, 
        'author':author, 
        'genre':genre
      })
      .then(res => {
        dispatch(addBookSuccess(res.data))
      })
      .catch(err => {
          dispatch(addBookFailure(err.message))
      })

post request is expecting a key-value body parser

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM