sql >> Base de Datos >  >> NoSQL >> MongoDB

¿Cómo empujar a una matriz MongoDB con AngularJS?

Hay un par de cosas aquí que no son geniales, pero primero para cubrir los conceptos básicos y ponerte en marcha.

Lo primero es arreglar el método llamando al servicio angular side. El punto final de la API ciertamente no espera la sintaxis de actualización de MongoDB que está utilizando, sino solo un objeto. Así que primero arreglar eso:

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

Ahora el extremo de la API de su servidor tiene algunas fallas, preferiría un rediseño total, pero por falta de información, solo concéntrese en solucionar los problemas principales sin cambiar mucho.

Asumiendo que este es el lodash biblioteca, el .merge() La función aquí se implementa incorrectamente. Es necesario decirle cómo "manejar" el contenido de la matriz en la "fusión" correctamente y, en la actualidad, lo mejor que sucederá es una "sobrescritura". Así que le damos un poco de inteligencia:

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

Pero hay una trampa para eso, ya que solo se "agregará" a la matriz. Entonces, si coloca algo en su entrada que ya estaba allí, se agregarán tanto los elementos originales como cualquier cosa en la entrada de la matriz.

Lidiar con eso es un problema completamente diferente que resolver, según sus necesidades.

Desde mi propia perspectiva, solo enviaría la matriz donde sea posible y tendría un punto final que es "solo" para agregar a la matriz del documento, en lugar de una actualización de documento "genérica" ​​como la que tiene aquí.

Esto le permite utilizar mejor las funciones de actualización de MongoDB, según las acciones esperadas. Así que algo como esto en la llamada de servicio:

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

Y en el extremo de la API del servidor:

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

Entonces eso simplemente tomará el cuerpo de un "comentario" y lo agregará a la matriz. Lo más importante es que hace esto "atómicamente", de modo que ninguna otra solicitud posible pueda colisionar al hacer algo como lo que está haciendo la "fusión" actual. Otras solicitudes al mismo punto final simplemente se "agregarán" a la matriz en el estado actual como cuando se realizó la solicitud, y esto también.

Eso es lo que dice $push operador es para, por lo que es aconsejable usarlo.

Algo para reflexionar.