MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Wie kann man mit AngularJS auf ein MongoDB-Array pushen?

Es gibt hier ein paar Dinge, die nicht großartig sind, aber zuerst, um die Grundlagen abzudecken und Sie zum Laufen zu bringen.

Als Erstes muss die Methode repariert werden, die die Dienstwinkelseite aufruft. Der API-Endpunkt erwartet sicherlich nicht die von Ihnen verwendete MongoDB-Aktualisierungssyntax, sondern nur ein Objekt. Also zuerst das beheben:

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

Jetzt hat Ihr Server-API-Ende einige Fehler, ich würde ein komplettes Redesign bevorzugen, aber mangels Informationen, konzentrieren Sie sich nur auf die Behebung der Hauptprobleme, ohne viel zu ändern.

Angenommen, dies ist der lodash Bibliothek, die .merge() hier ist die Funktion falsch implementiert. Es muss gesagt werden, wie der Array-Inhalt in der "Zusammenführung" richtig "handhabt" wird, und derzeit ist das Beste, was passieren wird, ein "Überschreiben". Also geben wir ihm ein paar Tricks:

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

Aber das hat einen Haken, da es nur an das Array "angehängt" wird. Wenn Sie also etwas in Ihre Eingabe einfügen, das bereits vorhanden war, werden sowohl die ursprünglichen Elemente als auch alles in der Array-Eingabe hinzugefügt.

Damit umzugehen, ist eine ganz andere Sache, die Sie je nach Ihren Bedürfnissen lösen müssen.

Aus meiner eigenen Perspektive würde ich das Array nach Möglichkeit nur senden und einen Endpunkt haben, der "nur" zum Anhängen an das Array des Dokuments dient, und nicht ein "generisches" Dokument-Update, wie Sie es hier haben.

Dadurch können Sie die MongoDB-Aktualisierungsfunktionen je nach erwarteten Aktionen besser nutzen. Also etwa so im Serviceaufruf:

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

Und auf der Seite der Server-API:

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

Das nimmt also einfach den Text eines "Kommentars" und hängt ihn an das Array an. Am wichtigsten ist, dass es dies "atomar" tut, so dass keine andere mögliche Anforderung kollidieren könnte, wenn es so etwas wie die aktuelle "Merge" tut. Andere Anfragen an denselben Endpunkt werden einfach an das Array im aktuellen Zustand "angehängt", als ob die Anfrage gestellt wurde, und das wird auch so sein.

Dafür steht der $push Operator ist für, also ist es ratsam, ihn zu verwenden.

Einige Denkanstöße.