Comment pousser sur un tableau MongoDB avec AngularJS?

J’essaie d’append une série de commentaires à un tableau MongoDB avec le service $ http d’AngularJS, mais il semble que je sois tombé dans une impasse. Voici le code que j’ai essayé (qui a planté mon DOM):

$scope.saveComment = function(i){ console.log("id is " + i); $http.put('/api/its/' + i, { comments: {$push: { words: $scope.comment, userId: $scope.getCurrentUser().name } } } ).success(function(stuff){ document.location.reload(true); }) } 

J’essayais d’utiliser la méthode $push MongoDB pour faire cela, mais Angular ne l’aurait pas. Un indice sur la façon dont je pourrais faire ça?

Cordialement,

Peter

PS

Voici le code côté serveur pour la fonctionnalité de mise à jour de ce modèle particulier:

 // 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); updated.save(function (err) { if (err) { return handleError(res, err); } return res.json(200, it); }); }); };` 

Il y a quelques points ici qui ne sont pas géniaux, mais d’abord pour couvrir les bases et vous permettre de commencer.

La première chose à faire est de corriger la méthode d’appel du côté angular du service. Le sharepoint terminaison de l’API n’attend certainement pas la syntaxe de mise à jour MongoDB que vous utilisez, mais plutôt un object. Donc, d’abord réparer ç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, votre API de serveur fin a quelques défauts, je préférerais une refonte totale, mais faute d’informations, nous nous concentrons simplement sur la résolution des problèmes principaux sans trop changer.

En supposant qu’il s’agisse de la bibliothèque lodash , la fonction .merge() est implémentée de manière incorrecte. Il faut savoir comment “manipuler” correctement le contenu du tableau dans la “fusion”, et actuellement, le mieux qui puisse arriver est un “écrasement”. Nous lui donnons donc quelques connaissances:

 // 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 inconvénient à cela, car cela ne fera qu ‘”append” au tableau. Donc, si vous mettez quelque chose dans votre entrée qui était déjà là, alors les éléments originaux et tout ce qui est dans l’entrée du tableau seront ajoutés.

Faire face à cela est un tout autre problème à régler, selon vos besoins.

De mon sharepoint vue, je voudrais simplement envoyer le tableau dans la mesure du possible et avoir un sharepoint terminaison “juste” pour l’ajout 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, en fonction des actions attendues. Donc, quelque chose comme ceci 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); } ); }; 

Cela prend donc simplement le corps d’un “commentaire” et l’ajoute au tableau. Plus important encore, il effectue cette opération de manière “atomique”, de sorte qu’aucune autre requête possible ne puisse entrer en collision si l’on procède de la même manière que la “fusion” actuelle. Les autres demandes adressées au même sharepoint terminaison “s’appendont” au tableau dans l’état actuel comme lors de la demande, et il en ira de même.

C’est ce à quoi sert l’opérateur $push , il est donc sage de l’utiliser.

Quelques pistes de reflection.