发布到 mongoDB 与 redux/redux-thunk 互动
Posting to mongoDB in react with redux/redux-thunk
模拟库
显示数据库中的书籍(作者标题流派)以及添加书籍的能力。
正在从我的 React 组件中正确获取数据。
数据以实物形式传递给我的 action creator,同样由 reducer 正确处理。
似乎我的异步 thunk 已正确设置为使用 axios 发出 post 请求。我正在通过获取请求正确获取数据库中已有的书籍。
我的路线似乎有效,因为我能够使用 postman 正确添加一本书并获取所有书籍。再一次,从我的反应组件中获取时,我的书可以正确显示。
问题出在哪里?为什么我的 post 请求没有到达我的数据库?
我的行为--
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
});
我的减速器--
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
}
}
错误--
{ 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(路线)
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)
})
书本模型
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);
您可能需要在 axios 设置中支持完整的 url 主机,还请 post 上下文错误日志
axios 调用的一个小改动
axios
.post('/books', {
'title':title,
'author':author,
'genre':genre
})
.then(res => {
dispatch(addBookSuccess(res.data))
})
.catch(err => {
dispatch(addBookFailure(err.message))
})
post 请求需要键值正文解析器
在我的 server.js
中,我遗漏了以下内容:
...
app.use(bodyParser.json());
...
模拟库 显示数据库中的书籍(作者标题流派)以及添加书籍的能力。
正在从我的 React 组件中正确获取数据。
数据以实物形式传递给我的 action creator,同样由 reducer 正确处理。
似乎我的异步 thunk 已正确设置为使用 axios 发出 post 请求。我正在通过获取请求正确获取数据库中已有的书籍。
我的路线似乎有效,因为我能够使用 postman 正确添加一本书并获取所有书籍。再一次,从我的反应组件中获取时,我的书可以正确显示。
问题出在哪里?为什么我的 post 请求没有到达我的数据库?
我的行为--
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
});
我的减速器--
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
}
}
错误--
{ 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(路线)
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)
})
书本模型
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);
您可能需要在 axios 设置中支持完整的 url 主机,还请 post 上下文错误日志
axios 调用的一个小改动
axios
.post('/books', {
'title':title,
'author':author,
'genre':genre
})
.then(res => {
dispatch(addBookSuccess(res.data))
})
.catch(err => {
dispatch(addBookFailure(err.message))
})
post 请求需要键值正文解析器
在我的 server.js
中,我遗漏了以下内容:
...
app.use(bodyParser.json());
...