Come passare a un array MongoDB con AngularJS?

Sto provando ad aggiungere una serie di commenti a un array MongoDB con il servizio $ http di AngularJS, ma mi sembra di aver raggiunto un punto morto. Ecco il codice che ho provato (che ha causato il crash del mio 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); }) } 

Stavo cercando di usare il metodo $push MongoDB per farlo, ma Angular non ce l’ha. Qualche idea su come potrei fare questo?

Cordiali saluti,

Peter

PS

Ecco il codice lato server per la funzionalità di aggiornamento di quel particolare modello:

 // 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); }); }); };` 

Ci sono un paio di cose qui che non sono grandiose, ma prima di coprire le basi e farti andare avanti.

La prima cosa è risolvere il metodo chiamando il lato angular del servizio. L’endpoint API di certo non si aspetta la syntax di aggiornamento di MongoDB che stai usando, ma piuttosto solo un object. Quindi prima aggiustare questo:

 $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); }); } 

Ora la tua API server ha qualche difetto, io preferirei una riprogettazione totale, ma in mancanza di informazioni, concentrandomi solo sulla risoluzione dei problemi principali senza cambiare molto.

Supponendo che questa sia la libreria di lodash , la funzione .merge() qui è implementata in modo errato. Deve essere detto come “gestire” correttamente il contenuto dell’array nella “fusione”, e al momento il meglio che accadrà è una “sovrascrittura”. Quindi gli diamo un po ‘di intelligenza:

 // 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); }); }); };` 

Ma c’è una presa in tal senso, in quanto verrà “aggiunta” all’array. Quindi se metti qualcosa nel tuo input che era già lì, allora saranno aggiunti sia gli elementi originali che qualsiasi cosa nell’ingresso dell’array.

Trattare con questo è un altro problema da risolvere, a seconda delle esigenze.

Dal mio punto di vista, vorrei semplicemente inviare l’array dove ansible e avere un endpoint che è “solo” per accodare l’array del documento, piuttosto che un aggiornamento di documento “generico” come qui.

Ciò consente di utilizzare al meglio le funzioni di aggiornamento di MongoDB, in base alle azioni previste. Quindi qualcosa di simile nella chiamata di servizio:

 // comment can just be a singular object now $http.put(path,{ "words": "this that", "userId": 123 }).success(function(stuff){ 

E alla fine dell’API del server:

 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); } ); }; 

In questo modo prenderà semplicemente il corpo di un “commento” e lo aggiungerà all’array. Soprattutto lo fa “atomicamente”, in modo che nessuna altra ansible richiesta possa scontrarsi nel fare qualcosa di simile all’attuale “unione”. Altre richieste allo stesso endpoint verranno semplicemente “accodate” all’array nello stato corrente come quando viene effettuata la richiesta, e così sarà.

Ecco a cosa serve l’operatore $push , quindi è consigliabile utilizzarlo.

Qualche spunto di riflessione