使用 Angular 2 服务、mongoDB 和 NodeJs 编辑对象

Posted

技术标签:

【中文标题】使用 Angular 2 服务、mongoDB 和 NodeJs 编辑对象【英文标题】:Edit object using angular2+ service, mongoDB & NodeJs 【发布时间】:2018-01-10 19:46:46 【问题描述】:

我想对存储在数据库 (mongoDB) 中的数据进行基本编辑。 这是我所做的:

角度服务

createReview(review) 

    let headers = new Headers();
    headers.append('Content-Type', 'application/json');

    this.http.post('http://localhost:3000/api/reviews', JSON.stringify(review),  headers: headers )
      .subscribe(res => 
        console.log(res.json());
      );

  
editReview(review) 

    let headers = new Headers();
    headers.append('Content-Type', 'application/json');
    this.http.post('http://localhost:3000/api/reviews', JSON.stringify(review),  headers: headers )
      .subscribe(res => 
        console.log(res.json());
      );
  

deleteReview(id)

this.http.delete('http://localhost:3000/api/reviews/' + id).subscribe((res) => 
  console.log(res.json());
);

在 server.js 中

// Set up
var express = require('express');
var app = express(); // create our app w/ express
var mongoose = require('mongoose'); // mongoose for mongodb
var ObjectId = require('mongodb').ObjectID; // objectID
var morgan = require('morgan'); // log requests to the console (express4)
var bodyParser = require('body-parser'); // pull information from html POST (express4)
var methodOverride = require('method-override'); // simulate DELETE and PUT (express4)
var cors = require('cors');

// Configuration
mongoose.connect('mongodb://localhost/data');

app.use(morgan('dev')); // log every request to the console
app.use(bodyParser.urlencoded( 'extended': 'true' )); // parse application/x-www-form-urlencoded
app.use(bodyParser.json()); // parse application/json
app.use(bodyParser.json( type: 'application/vnd.api+json' )); // parse application/vnd.api+json as json
app.use(methodOverride());
app.use(cors());

app.use(function(req, res, next) 
    res.header("Access-Control-Allow-Origin", "*");
    res.header('Access-Control-Allow-Methods', 'DELETE, PUT');
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
);

// Models
var Review = mongoose.model('Review', 
    title: String,
    description: String,
    rating: Number
);

// Routes

// Get reviews
app.get('/api/reviews', function(req, res) 

    console.log("fetching reviews");

    // use mongoose to get all reviews in the database
    Review.find(function(err, reviews) 

        // if there is an error retrieving, send the error. nothing after res.send(err) will execute
        if (err)
            res.send(err)

        res.json(reviews); // return all reviews in JSON format
    );
);


// create review and send back all reviews after creation
app.post('/api/reviews', function(req, res) 
    if (req.params.review_id == undefined) 
        console.log("creating review");

        // create a review, information comes from request from Ionic
        Review.create(
            title: req.body.title,
            description: req.body.description,
            rating: req.body.rating,
            done: false
        , function(err, review) 
            if (err)
                res.send(err);

            // get and return all the reviews after you create another
            Review.find(function(err, reviews) 
                if (err)
                    res.send(err)
                res.json(reviews);
            );
        );
     else 
        console.log("editing review")
        var query = ObjectId(req.params.review_id);

        // update a review, information comes from request from Ionic
        Review.findOneAndUpdate(query, 
            title: req.body.title,
            description: req.body.description,
            rating: req.body.rating,
            done: false
        , function(err, review) 
            if (err)
                res.send(err);

            // get and return all the reviews after you create another
            Review.find(function(err, reviews) 
                if (err)
                    res.send(err)
                res.json(reviews);
            );
        );
    
);

// delete a review
app.delete('/api/reviews/:review_id', function(req, res) 
    console.log("deleting review");
    Review.remove(
        _id: req.params.review_id
    , function(err, review) 

    );
);


// listen (start app with node server.js) ======================================
app.listen(3000);
console.log("App listening on port 3000");

创建一个新的评论可以正常工作,也可以删除评论。但是在编辑时,我从 server.js 的 app.post 函数中的 req.params.review_id 得到未定义的错误。 我确定我没有以正确的方式做到这一点。 如何使用这些库和框架更新数据?

【问题讨论】:

很明显,您正在尝试从 params 获取 review_id,但您没有在 params 中传递它,因为您正在传递 delete 调用。您可以使用 /:re​​view_id 修改 post 调用,或者尝试从 req.body._id 或您使用的任何参数获取 review_id。放一个console.log,看看你为req.params和req.body得到了什么值 这是奇怪的事情 req.params 和 req.body 返回空对象。此外,当我将 /:re​​view_id 作为参数时,它在我创建新评论时将不起作用 【参考方案1】:

如 cmets 中所述,您使用了一个参数,该参数未在您的 express 应用程序的路由中定义。

您可以通过将路由定义编写为:

使参数可选(将与 create 和 edit 一起使用):
app.post('/api/reviews/:review_id?', function(req, res) 
  /* .... */
 );

请记住,遵循正确的 REST 架构,您应该在 PUT 请求中分离实体的编辑。

app.post( '/api/reviews', function( req, res )  /** Handle Create */  );
app.put( '/api/reviews/:review_id', function( req, res )  /** Handle Edits */  );

【讨论】:

根据这个网站,put 是创建,post 是编辑。 tutorialspoint.com/nodejs/nodejs_restful_api.htm ***.com/questions/630453/put-vs-post-in-rest 仅适用于您(客户)定义该实体的标识的情况。这种情况很少发生。通常,在您的情况下,服务器也会这样做。

以上是关于使用 Angular 2 服务、mongoDB 和 NodeJs 编辑对象的主要内容,如果未能解决你的问题,请参考以下文章

在后端使用NodeJS的Put方法不更新Angular7中的MongoDB

Apollo Angular 无法从 GraphQL/MongoDB 获取数据

Angular 5 - 实现数据服务以从 MongoDB 读取 JSON

无法使用 express API 和节点 JS(Angular 4)将数据发布到 mongodb

如何使用 angular 和 nodejs 将 csv 数据转储到 mongoDB

错误状态:使用 Node.js (express)、Angular 和 MongoDB 的 PUT 请求返回 404