Il y a quelques choses ici qui ne sont pas géniales, mais d'abord pour couvrir les bases et vous lancer.
La première chose à faire est de corriger la méthode appelant le service angular side. Le point de terminaison de l'API n'attend certainement pas la syntaxe de mise à jour MongoDB que vous utilisez, mais plutôt un objet. Donc d'abord corriger ça :
$scope.saveComment = function(i){
console.log("id is " + i);
// Split these out so they are easy to log and debug
var path = '/api/its' + i;
// This must mirror the structure expected in your document for the element
// Therefore "comments" is represented as an array of objects, even
// where this is only one.
var data = {
comments: [{
words: $scope.comment,
userId: $scope.getCurrentUser().name
}]
};
// Call service with response
$http.put(path,data).success(function(stuff){
document.location.reload(true);
});
}
Maintenant que votre API de serveur a quelques défauts, je préférerais une refonte totale, mais en manque d'informations, concentrez-vous simplement sur la résolution des principaux problèmes sans trop changer.
En supposant qu'il s'agit du lodash
bibliothèque, la .merge()
fonction ici est implémentée de manière incorrecte. Il faut lui dire comment "gérer" correctement le contenu du tableau dans la "fusion", et à l'heure actuelle, le mieux qui se produira est un "écrasement". Nous lui donnons donc un peu d'intelligence :
// Updates an existing it in the DB.
exports.update = function(req, res) {
if(req.body._id) { delete req.body._id; }
It.findById(req.params.id, function (err, it) {
if (err) { return handleError(res, err); }
if(!it) { return res.send(404); }
var updated = _.merge(it, req.body,function(a,b) {
if (_.isArray(a)) {
return a.concat(b); // join source and input
}
});
updated.save(function (err) {
if (err) { return handleError(res, err); }
return res.json(200, updated);
});
});
};`
Mais il y a un hic à cela, car il ne fera que "s'ajouter" au tableau. Donc, si vous mettez quelque chose dans votre entrée qui s'y trouvait déjà, les éléments d'origine et tout ce qui se trouve dans l'entrée du tableau seraient ajoutés.
Gérer cela est un tout autre problème à résoudre, en fonction de vos besoins.
De mon point de vue, j'enverrais simplement le tableau dans la mesure du possible et j'aurais un point de terminaison qui est "juste" à ajouter au tableau du document, plutôt qu'une mise à jour de document "générique" comme vous l'avez ici.
Cela vous permet de mieux utiliser les fonctions de mise à jour de MongoDB, par actions attendues. Donc, quelque chose comme ça dans l'appel de service :
// comment can just be a singular object now
$http.put(path,{
"words": "this that",
"userId": 123
}).success(function(stuff){
Et du côté de l'API du serveur :
exports.addComment = function(req, res) {
if(req.body._id) { delete req.body._id; }
It.findByIdAndUpdate(req.params.id,
{ "$push": { "comments": req.body } },
{ "new": true },
function(err,it) {
if (err) { return handleError(res, err); }
if(!it) { return res.send(404); }
return res.json(200, it);
}
);
};
Donc, cela prendra simplement le corps d'un "commentaire" et l'ajoutera au tableau. Plus important encore, il le fait "atomiquement", de sorte qu'aucune autre demande possible ne puisse entrer en collision en faisant quelque chose comme la "fusion" actuelle. Les autres requêtes adressées au même point de terminaison "s'ajouteront" simplement au tableau dans l'état actuel de la requête, et il en sera de même.
C'est ce que le $push
est pour, il est donc sage de l'utiliser.
Quelques pistes de réflexion.