2

我一直在试图弄清楚如何将我的数据更新到 MongoDB(我将 Monk 与 MongoDB、Node、Express 和 Angular 一起使用)。我对 POST 和 DELETE 没有任何问题,但不知道 PUT 哪里出了问题。

我得到的错误:

PUT http://localhost:3000/api/habits/[object%20Object] 500 (Internal Server Error) 

我感到困惑的是我应该用 Angular 发送什么,以及如何在 Node 中接收它,因为我知道我需要发送更新的对象以进行记录,但是我应该如何访问 ID 来查找它在蒙古?

例如,使用我的 POST(下面有更多代码上下文),我发送对象“newHabitData”是有道理的

$http.post('http://localhost:3000/api/habits', newHabitData)

但是对于我看到的 PUT 示例,它们将对象(名为 id)作为 :parameter 发送

app.put('/api/articles/:id', function (req, res){

我一直在使用这些教程,这是我能找到的最接近了解如何使用 PUT 的教程: http: //aleksandrov.ws/2013/09/12/restful-api-with-nodejs-plus-mongodb/ http:// /scotch.io/tutorials/javascript/build-a-restful-api-using-node-and-express-4

一百万谢谢你的建议!

角度:

// Works Fine
$scope.addHabit = function(){
    var newTitle = $scope.newTitle.trim();
    if(!newTitle){
        return;
    }
    var newHabitData = {
        title: newTitle,
        count: 0,
        status: 'active'
    };

    $http.post('http://localhost:3000/api/habits', newHabitData)
        .success(function(data) {
            $scope.habitList = data;
            console.log(data);
        })
        .error(function(data) {
            console.log('Error: ' + data);
        });

    $('.habit-form__input-title').val('').focus();
    $scope.newTitle = '';

}

// Works Fine
$scope.habitDestroy = function (id) {       
    $http.delete('/api/habits/' + id._id)
        .success(function(data) {
            $scope.habitList = data;
            console.log(data);
        })
        .error(function(data) {
            console.log('Error: ' + data);
        });
};

// NOT WORKING - I WANT TO INCREMENT THE COUNT, THEN SAVE
$scope.habitCheckIn = function(id){             
    id.count = ++id.count;

    $http.put('/api/habits/' + id)  // Should I be sending the entire object? Seems to make most sense to me
        .success(function(data) {
            $scope.habitList = data;
            console.log(data);
        })
        .error(function(data) {
            console.log('Error: ' + data);
        });
}

节点:

// Get all habits -- WORKS FINE
router.get('/api/habits', function(req, res) {
    var db = req.db;
    var collection = db.get('habits');
    collection.find({},{},function(e,data){
        res.json(data);
    });
});

// Create one habit -- WORKS FINE
router.post('/api/habits', function(req, res) {
    var db = req.db;
    var collection = db.get('habits');
    collection.find({},{},function(e,data){     
        collection.insert({ 
            title: req.body.title, 
            count: req.body.count  
        }, function(err, habit){
            if(err){
                res.send(err);
            }

            collection.find({},{},function(e,data){
                res.json(data);
            });
        });
    });
});

// Delete one habit -- WORKS FINE
router.delete('/api/habits/:habit_id', function(req, res){
    var db = req.db;
    var collection = db.get('habits');

    collection.find({},{},function(e,data){ 
        collection.remove({
            _id : req.params.habit_id
        }, function(err, todo){
            if(err){
                res.send(err);
            }

            collection.find({},{},function(e,data){
                res.json(data);
            });
        })
    })
})

// Update Habit -- NOT WORKING    
router.put('/api/habits/:habit_id', function(req, rest){
    var db = req.db;
    var collection = db.get('habits');

    // the real ID is _id, so should I be doing req.params.habit_id._id ? Or is findById asking for the entire object, and it finds the actual id itself? This is where I'm lost, can't figure it out.
    collection.findById(req.params.habit_id, function(e,data){  
        if(e){ res.send(e); }
        data.title = req.body.title;
        data.count = req.body.count;
        data.save(function(err){
            if(err){
                res.send(err);
            res.json(data);
            }
        })
    })
})

更新 - 下面的代码让它工作。 感谢 saintedlama 让我朝着正确的方向前进。

不确定这是否是正确的方法,但它确实有效。我通过访问 req.body 值来遵循我的 POST 格式,而不是作为参数传入的 id。

所以代替这个:

router.put('/api/habits/:habit_id', function(req, res) {

我这样做了:

router.put('/api/habits', function(req, res) {

然后我使用 req.body._id 和 req.body.count 值访问了 id 和更新的计数/标题

router.put('/api/habits', function(req, res) {
    var db = req.db;
    var collection = db.get('habits');
    var id = req.body._id;

    if(!req.body) { 
        return res.send(400); 
    } // 6

    collection.findById(id, function(e,data){  
        if(e) { 
            return res.send(500, e); 
        } // 1, 2

        if(!data) { 
            return res.send(404); 
        } // 3

        var update = { 
            title : req.body.title, 
            count : req.body.count 
        }; // 4

        collection.updateById(id, update, function(err) { // 5
            if(err) {
                return res.send(500, err);
            }

        });
    });
});
4

2 回答 2

3

更新现有习惯的代码片段应该可以正常工作,并进行一些小的更正

  1. 在错误运行时始终使用return
  2. 始终发回状态。在这种情况下,我们将发送 500
  3. 检查未找到并返回 404
  4. 使用简单的更新对象。这只会更新更新对象中包含的字段
  5. 和尚返回的mongodb文档没有保存功能,需要通过集合更新文档
  6. 检查请求是否有正文并发送 400 - Bad Request

您可以将对象 id 作为十六进制或 ObjectId 传递给Monk docs 中findById所述。

router.put('/api/habits/:habit_id', function(req, rest){
    var db = req.db;
    var collection = db.get('habits');

    if(!req.body) { return res.send(400); } // 6

    collection.findById(req.params.habit_id, function(e,data){  
        if(e) { return res.send(500, e); } // 1, 2

        if(!data) { return res.send(404); } // 3

        var update = { title : req.body.title, count : req.body.count }; // 4

        collection.updateById(req.params.habit_id, update, function(err) { // 5
            if(err) {
                return res.send(500, err);
            }

            res.json(data);
        });
    });
});

上面的代码可以通过findAndModifyMonk的功能进一步简化。

于 2014-08-20T15:53:42.587 回答
0

你必须这样做:

模型:

/**
 * Statics
 */
PostSchema.statics.load = function(id, cb) {
    this.findOne({
        _id: id
    }).populate('user', '_id name username email role').exec(cb);
};

控制器:

exports.post = function(req, res, next, id) {
    if (!/^[0-9a-fA-F]{24}$/.test(id)) {
        return res.jsonp(404,{
            error: 'Failed to load post with id ' + id
        });
    }
    Post.load(id, function(err, post) {
        if (err) {
            return next(err);
        }
        if (!post){
            return res.jsonp(404,{
                error: 'Failed to load post with id ' + id
            });
        }
        req.post = post;
        next();
    });
};

路线:

app.put('/admin/api/post/:postId', postController.update);
 app.param('postId', postController.post);

看一眼

http://expressjs.com/api#router.param

顺便提一句

.success(function(data) {
            $scope.habitList = data;
            console.log(data);
        })

应该

.success(function(data) {
            $scope.habitList = data.data;
            console.log(data.data);
        })
于 2014-08-20T15:18:38.127 回答