La función de agregado duplica los elementos en ng-repeat en la actualización de la página. Necesidad de averiguar cómo detener la duplicación. Angularjs mongodb mongoose

Tengo artículos en una colección que se ejecutan a través de este agregado para encontrarlos con una calificación promedio y para encontrarlos cuando aún no se hayan comentado o calificado.

Funciona, pero cada vez que actualizo la página ahora, se muestra un duplicado en la repetición ng de cada elemento de la colección de bourbon. La cantidad real de artículos en la colección de bourbon no está cambiando. ¿Cómo paro esto? LADO DEL SERVIDOR: esquema de bourbon:

'use strict'; var mongoose = require('mongoose'), BourbonSchema = null; module.exports = mongoose.model('Bourbon', { name: {type: String, required: true}, blog: {type: String, required: true}, photo: {type: String, required: true, default:'http://aries-wineny.com/wp-content/uploads/2014/09/woodford-reserve.jpg'}, location: {type: String, required: true}, distillery: {type: String, required: true}, comments: [{type: mongoose.Schema.ObjectId, ref: 'Comments'}], rating : {type: Number} }); var Bourbon = mongoose.model('Bourbon', BourbonSchema); module.exports = Bourbon; 

esquema de comentarios / calificaciones:

 'use strict'; var mongoose = require('mongoose'); module.exports = mongoose.model('Comment', { bourbonId: {type: mongoose.Schema.ObjectId, ref: 'Bourbon'}, userId: {type: mongoose.Schema.ObjectId, ref: 'User'}, text: {type: String, required: true}, createdAt: {type: Date, required: true, default: Date.now}, rating : {type: Number, required: true}, votes: {type: Number, default: 0} }); 

función agregada:

 'use strict'; var Bourbon = require('../../../models/bourbon'), Comment = require('../../../models/comment'), DataStore = require('nedb'), db = new DataStore(), async = require('async'); module.exports = { description: 'Get Bourbons', notes: 'Get Bourbons', tags: ['bourbons'], handler: function(request, reply){ async.series( [ function(callback){ Bourbon.find({},function(err,results){ //if (err) callback(err); async.eachLimit(results,10,function(result,callback){ var plain = result.toObject(); plain.bourbonId = plain._id.toString(); plain.avgRating = 0; delete plain._id; db.insert(plain,callback); },callback); }); }, function(callback){ Comment.aggregate( [ {$group:{ _id: '$bourbonId', avgRating:{$avg:'$rating'} }} ], function(err,results){ async.eachLimit(results,10,function(result,callback){ db.update( {bourbonId: result._id.toString()}, {$set: {avgRating: result.avgRating}}, callback ); },callback); } ); } ], function(err){ //if (err) callback(err); db.find({}, {_id: 0}, function(err, bourbons){ console.log('DOOOOCS', bourbons); reply ({bourbons:bourbons}); }); }); } }; 

Lado del cliente

 factory: (function(){ 'use strict'; angular.module('hapi-auth') .factory('Bourbon', ['$http', function($http){ function create(bourbon){ return $http.post('/admin', bourbon); } function all(){ return $http.get('/admin'); } return {create:create, all:all}; }]); })(); 

controlador:

 (function(){ 'use strict'; angular.module('hapi-auth') .controller('AdminCtrl', ['$scope', 'Bourbon', function($scope, Bourbon){ //$scope.blog.photo = []; $scope.bourbon = {}; $scope.bourbons = []; Bourbon.all().then(function(res){ $scope.bourbons = res.data.bourbons; console.log(res.data.bourbons); }); $scope.createBourbon = function(bourbon){ console.log('BOURBB', bourbon); Bourbon.create(bourbon).then(function(res){ console.log('bourboonnnn', res.data); $scope.bourbons.push(res.data); }); }; }]); })(); 

jade:

 .row .small-4.columns .small-4.columns .review .insertContainer(ng-repeat='bourbon in bourbons') .adminName Name: {{bourbon.name}} img.bourbonImg(src='{{bourbon.photo}}') .adminBlog {{bourbon.blog.slice(0,200)}} ... .small-4.columns 

tratando de detener la duplicación de elementos en la colección de bourbon en la actualización de la página … No estoy seguro si necesito implementar algún tipo de método de reemplazo aquí … un poco atascado ahora …

Esto es lo que el registro de la consola en la función de controlador / agregado devuelve:

 DOOOOCS [ { name: 'woodford reserve', location: 'kentucky', distillery: 'woodford', blog: 'fjkd;asdljfkld;ksdfj', __v: 0, comments: [], photo: 'http://aries-wineny.com/wp-content/uploads/2014/09/woodford-reserve.jpg', bourbonId: '54c2aa5556267e0000b5618c', avgRating: 0 }, { name: 'woodford reserve', location: 'kentucky', distillery: 'woodford', blog: 'fjkd;asdljfkld;ksdfj', __v: 0, comments: [], photo: 'http://aries-wineny.com/wp-content/uploads/2014/09/woodford-reserve.jpg', bourbonId: '54c2aa5556267e0000b5618c', avgRating: 0 } ] 

parece duplicar cada elemento en la colección de Borbones cada vez que se ejecuta esta función …, que se ejecuta en la actualización de la página como Bourbon.all dentro del controlador angular.

este es el bourbon en la colección, antes de que se ejecute a través del agregado:

 { "_id" : ObjectId("54c2aa5556267e0000b5618c"), "name" : "woodford reserve", "location" : "kentucky", "distillery" : "woodford", "blog" : "fjkd;asdljfkld;ksdfj", "comments" : [], "photo" : "http://sofes.miximages.com/angularjs/woodford-reserve.jpg", "__v" : 0 } 

jade actualizado con pista por:

 .row .small-4.columns .small-4.columns .review .insertContainer(ng-repeat='bourbon in bourbons | unique: bourbon.bourbonId | filter: query') .adminName Name: {{bourbon.name}} img.bourbonImg(src='{{bourbon.photo}}') .adminBlog {{bourbon.blog.slice(0,200)}} ... .small-4.columns 

esto permite que los elementos se muestren en la primera carga, pero en cualquier actualización / recarga, ahora aparece este error:

 Error: [ngRepeat:dupes] Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: bourbon in bourbons track by bourbon.bourbonId | filter:query, Duplicate key: 54c2aa5556267e0000b5618c, Duplicate value: {"name":"woodford reserve","location":"kentucky","distillery":"woodford","blog":"fjkd;asdljfkld;ksdfj","__v":0,"comments":[],"photo":"http://sofes.miximages.com/angularjs/woodford-reserve.jpg","bourbonId":"54c2aa5556267e0000b5618c","avgRating":0} http://errors.angularjs.org/1.3.8/ngRepeat/dupes?p0=bourbon%20in%20bourbons…C%22bourbonId%22%3A%2254c2aa5556267e0000b5618c%22%2C%22avgRating%22%3A0%7D at http://localhost:7070/vendor/angular/angular.js:63:12 at ngRepeatAction (http://localhost:7070/vendor/angular/angular.js:24483:21) at Object.$watchCollectionAction [as fn] (http://localhost:7070/vendor/angular/angular.js:14092:13) at Scope.$digest (http://localhost:7070/vendor/angular/angular.js:14225:29) at Scope.$apply (http://localhost:7070/vendor/angular/angular.js:14488:24) at done (http://localhost:7070/vendor/angular/angular.js:9646:47) at completeRequest (http://localhost:7070/vendor/angular/angular.js:9836:7) at XMLHttpRequest.requestLoaded (http://localhost:7070/vendor/angular/angular.js:9777:9) 

estos son los elementos de bourbon que se devuelven en la consola del navegador. todos ellos tienen el mismo bourbonId, comenzando con el índice 0. El filtro único está devolviendo 2 objetos bourbon ahora, (¿el original y uno de los duplicados?) en lugar de todos …:

[Objeto, Objeto, Objeto, Objeto, Objeto] 0: Objeto $$ hashKey: “objeto: 6” v: 0avgRating: 4blog: “fjkd; asdljfkld; ksdfj” bourbonId: “54c2aa5556267e0000b5618c” comentarios: Array [0] distillery: ” woodford “location:” kentucky “name:” woodford reserve “photo:” http://aries-wineny.com/wp-content/uploads/2014/09/woodford-reserve.jpg “__proto : Object1: Object__v: 0avgRating: 4blog: “fjkd; asdljfkld; ksdfj” bourbonId: “54c2aa5556267e0000b5618c” comentarios: Array [0] destilería: “woodford” ubicación: “kentucky” nombre: “woodford reserve” foto: ” http://sofes.miximages.com/angularjs/ woodford-reserve.jpg ” proto : Object2: Object $$ hashKey:” object: 7 ” v: 0avgRating: 0blog:” fjkd; asdljfkld; ksdfj “bourbonId:” 54c2aa5556267e0000b5618c “comments: Array [0] longitud: 0__proto : Array [0] destilería: “woodford” ubicación: “kentucky” nombre: “woodford reserve” foto: ” http://sofes.miximages.com/angularjs/ woodford-reserve.jpg ” proto : Object3: Object__v: 0avgRating: 0blog:” fjkd; asdljfkld; ksdfj “bourbonId:” 54c2aa 5556267e0000b5618c “comentarios: Array [0] longitud: 0__proto__: Array [0] destilería:” woodford “ubicación:” kentucky “nombre:” woodford reserve “foto:” http://sofes.miximages.com/angularjs/woodford-reserve.jpg ” proto : Object4: Object__v: 0avgRating: 0blog:” fjkd; asdljfkld; ksdfj “bourbonId:” 54c2aa5556267e0000b5618c “Comentarios: Array [0] longitud: 0__proto__: Array woodford “location:” kentucky “name:” woodford reserve “photo:” http://aries-wineny.com/wp-content/uploads/2014/09/woodford-reserve.jpg ” proto : Objectlength: 5__proto__: Array [ 0]


Creo que he reducido esto a ser un problema en el lado del servidor, dentro del controlador / agregado mencionado anteriormente. Necesito encontrar una manera de reemplazar los documentos actualizados, en lugar de crear uno nuevo cada vez que se llama / ejecuta Bourbon.all en el lado del cliente / navegador … tratando de abordarlo ahora. Cualquier consejo, muy apreciado.

Esto parece ser solo un caso de tomar un ejemplo demasiado literalmente. Está terminando con una salida duplicada en cada solicitud porque así es como está dentro del scope de la tienda de donde provienen los resultados.

Así que en lugar de esto:

 'use strict'; var Bourbon = require('../../../models/bourbon'), Comment = require('../../../models/comment'), DataStore = require('nedb'), db = new DataStore(), // <-- globally scoped in the module :( async = require('async'); module.exports = { description: 'Get Bourbons', notes: 'Get Bourbons', tags: ['bourbons'], handler: function(request, reply){ async.series( [ function(callback){ 

Más bien haz esto:

 'use strict'; var Bourbon = require('../../../models/bourbon'), Comment = require('../../../models/comment'), DataStore = require('nedb'), async = require('async'); module.exports = { description: 'Get Bourbons', notes: 'Get Bourbons', tags: ['bourbons'], handler: function(request, reply){ db = new DataStore(); // <--- Init store within request scope :) async.series( [ function(callback){ 

Eso parece ser un problema desde el lado del servidor agregar seguimiento por $ índice arreglará el problema.

ng-repeat='bourbon in bourbons track by $index

Pero la cosa es que mostrará los registros duplicados.

Mejor usas AngularUI angular.unique filter

Primero agregue el JS desde el enlace y luego agregue el módulo ‘ui.filters’ dentro de la dependencia de la aplicación.

ng-repeat='bourbon in bourbons | unique:'bourbonId'

Espero que esto resuelva su problema.

Gracias.