【发布时间】:2020-08-10 07:11:46
【问题描述】:
我在model.js 文件中分离了我的Mongoose 代码,而用于处理http 请求的Express 代码在app.js 中。我只是在为一个虚构的 wiki 文章站点练习创建 API 并在 Postman 上对其进行测试。问题在于findOneAndUpdate api。它正在按预期更改数据库文档,但是,传递给findOneAndUpdate api 回调的假定更新文档只是原始文档(修改前),而不是新更新的文档。我控制台记录了它只是为了确认。理想的做法是在回调中传递新更新的文档,以便万一我需要将新更新的文档作为 JSON 中的响应发送,只是为了显示更改确认。
我在下面分享了我的代码。
(注意:为简洁起见,我只包含了相关代码,即来自app.js 的app.put('/articles/:articleTitle' ....,以及它从model.js - updateReplaceArticleInDB 调用的静态方法。
app.js
const express = require('express');
const bodyParser = require('body-parser');
const model = require('./model');
const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.put('/articles/:articleTitle', async (req, res) => {
const articleTitle = req.params.articleTitle;
const newArticleTitle = req.body.title;
const newArticleContent = req.body.content;
try {
const response = await model.DBUtility.updateReplaceArticleInDB(articleTitle, newArticleTitle, newArticleContent);
res.json({message: 'Successfully overwritten article', updatedArticle: response, app: 'wiki-api'});
} catch (err) {
res.json({message: err, app: 'wiki-api'});
}
});
const port = 3000;
app.listen(port, () => {
console.log(`Server started on port ${port}`);
});
model.js
const mongoose = require('mongoose');
//connect to DB
mongoose.connect('mongodb://localhost:27017/wikiDB', {useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false },
(err) => {
try {
console.log(`Server connected successfully to MongoDB`);
} catch (err) {
console.log(err);
}
});
const articleSchema = new mongoose.Schema({
title: String,
content: String
});
const Article = mongoose.model('Article', articleSchema);
class DBUtility {
static updateReplaceArticleInDB(articleTitle, newArticleTitle, newArticleContent) {
return new Promise((resolve, reject) => {
Article.findOneAndUpdate(
{title: articleTitle},
{$set: {title: newArticleTitle, content: newArticleContent}}, (err, updatedArticle) => {
if (err) {
reject(err);
} else {
console.log(`updatedArticle: ${updatedArticle}`);
resolve(updatedArticle);
}
});
});
}
}
exports.DBUtility = DBUtility;
我的数据库中有 5 篇文章(5 个文档):
{
"_id" : "5c139771d79ac8eac11e754a",
"title" : "API",
"content" : "API stands for Application Programming Interface. It is a set of subroutine definitions, communication protocols, and tools for building software. In general terms, it is a set of clearly defined methods of communication among various components. A good API makes it easier to develop a computer program by providing all the building blocks, which are then put together by the programmer."
}
/* 2 */
{
"_id" : "5c1398aad79ac8eac11e7561",
"title" : "Bootstrap",
"content" : "This is a framework developed by Twitter that contains pre-made front-end templates for web design"
}
/* 3 */
{
"_id" : "5c1398ecd79ac8eac11e7567",
"title" : "DOM",
"content" : "The Document Object Model is like an API for interacting with our HTML"
}
/* 4 */
{
"_id" : "5ea2c188fa57aa1b6453eda5",
"title" : "Node JS",
"content" : "Node.js is an open-source, cross-platform, JavaScript runtime environment that executes JavaScript code outside of a web browser. Node.js lets developers use JavaScript to write command line tools and for server-side scripting—running scripts server-side to produce dynamic web page content before the page is sent to the user's web browser. Consequently, Node.js represents a \"JavaScript everywhere\" paradigm,[6] unifying web-application development around a single programming language, rather than different languages for server- and client-side scripts.",
"__v" : 0
}
/* 5 */
{
"_id" : "5ea2d5304e19b11e0013a86a",
"title" : "Bootstrap",
"content" : "Bootstrap is an open source
toolkit for developing with HTML, CSS, and JS. Quickly prototype your ideas or build your entire app with our Sass variables and mixins, rins, responsive grid system, extensive prebuilt components, and powerful plugins
built on jQuery.",
"__v" : 0
}
目标是将最后一个文档"title" : "Bootstrap" 更改为"title" : "EJS" 和"content" : "EJS is a simple templating language ..."。
但是,当我在 Postman 上发出 http 请求时,返回的文档(应该是新更新的文档)不是。它显示为原来的旧版本(即"title": "Bootstrap" 而不是"title": "EJS"):
在终端中,控制台记录的updatedArtilce对象传递给updateReplaceArticleInDB api的回调也显示旧文章title: Bootstrap,而不是更新后的EJS:
[nodemon] starting `node app.js`
Server started on port 3000
Server connected successfully to MongoDB
updatedArticle: {
_id: 5ea2d5304e19b11e0013a86a,
title: 'Bootstrap',
content: 'Bootstrap is an open source
toolkit for developing with HTML, CSS, and JS. Quickly prototype your ideas or build your entire app with our Sass variables and mixins, rins, responsive grid system, extensive prebuilt components, and powerful plugins
built on jQuery.'
}
但数据库确实成功更改了文档。只是 Mongoose API 在其回调中传递旧文档而不是新更新的文档。
【问题讨论】:
-
添加
{new: true}作为 findOneAndUpdate 查询的一部分 -
太棒了。谢谢。
标签: node.js mongodb express mongoose