I use react redux toolkit with node.js. I have been spending hours trying to figure out why req.body is empty (with an update function). The express.json() middleware is well defined in server.js.
backend - servers.js :
const express = require('express');
const cors = require('cors');
const dotenv = require('dotenv').config();
const { errorHandler } = require('./middleware/errorMiddleware');
const connectDB = require('./config/db');
const port = process.env.PORT || 5000;
connectDB();
const app = express();
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use('/api/books', require('./routes/bookRoutes'));
app.use(errorHandler);
app.listen(port, () => console.log(`Server started on port ${port}`));
backend - bookRoutes.js :
...
router.put('/:id', updateBook);
backend - bookController.js :
const asyncHandler = require('express-async-handler');
const updateBook = asyncHandler(async (req, res) => {
const book = await Book.findById(req.params.id);
if (!book) {
res.status(400);
throw new Error('Book not found');
}
console.log('backend bookController req body: ', req.body);
`//output : backend bookController req body: {}`
const updatedBook = await Book.findByIdAndUpdate(req.params.id, req.body, {
new: true,
});
res.status(200).json(updatedBook);
});
frontend - booksSlice.js :
const initialState = {
books: [],
isLoading: false,
isSuccess: false,
isError: false,
message: '',
};
//Update book
export const updateBook = createAsyncThunk(
'books/update',
async ({ id, bookData }, thunkAPI) => {
try {
console.log('slice bookData : ', bookData);
`//output: slice bookData : undefined`
return await bookService.updateBook(id, bookData);
} catch (error) {
const message =
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString();
return thunkAPI.rejectWithValue(message);
}
}
);
frontend - bookService.js :
const API_URL = 'http://localhost:5000/api/books/';
// Update user book
const updateBook = async (bookId, bookData) => {
console.log('axios service bookData: ', bookData);
`//output: slice service: undefined`
const response = await axios.put(API_URL + bookId, bookData);
return response.data;
};
frontend UpdateBook.jsx
const UpdateBook = () => {
const { id } = useParams();
const books = useSelector((state) => state.books.books);
const book = books.find((b) => b._id === id);
const dispatch = useDispatch();
const [title, setTitle] = useState(book.title);
const [description, setDescription] = useState(book.description);
const [author, setAuthor] = useState(book.author);
const handleSubmitButton = (id) => {
const bookUpdated = {
title: title,
description: description,
author: author,
};
dispatch(updateBook({ id, bookUpdated }));
};
return (
<div className="form">
<div className="title">Update</div>
<div className="subtitle">Let's update a book!</div>
<div className="input-container ic1">
<input
id="title"
className="input"
type="text"
placeholder=" "
value={title}
onChange={(e) => {
setTitle(e.target.value);
}}
/>
<div className="cut" />
<label htmlFor="title" className="placeholder">
Title
</label>
</div>
<div className="input-container ic2">
<input
id="description"
className="input"
type="text"
placeholder=" "
value={description}
onChange={(e) => {
setDescription(e.target.value);
}}
/>
<div className="cut" />
<label htmlFor="description" className="placeholder">
description
</label>
</div>
<div className="input-container ic2">
<input
id="text"
className="input"
type="text"
placeholder=" "
value={author}
onChange={(e) => {
setAuthor(e.target.value);
}}
/>
<div className="cut cut-short" />
<label htmlFor="text" className="placeholder">
Author
</label>
</div>
<button
onClick={() => handleSubmitButton(book._id)}
type="text"
className="submit"
>
Update book!
</button>
</div>
);
};
export default UpdateBook;
Note that with postman the update function works. An idea to solve my problem? Thanks.
EDIT : Could you please see my code: CodeSandbox .
Launch at port 3000 on the browser panel [Browser(:3000)]: k971xu-3000.sse.codesandbox.io/. See on the terminal and console: after update req-body is empty. Note that the create function works... An idea to solve my problem? Thanks.
I think, In backend - bookController.js, you have done something. Refer express-async-handler . And also you have not exported the controller. Therefore, in backend - bookController.js: , export your controller.
exports.updateBook = updateBook;
In backend - bookRoutes.js:
const bookController = require(<"path of your controller file">);
router.put('/:id',asyncHandler(bookController.updateBook));
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.