Агрегатная функция дублирует элементы в ng-repeat при обновлении страницы. Нужно выяснить, как остановить дублирование. Angularjs Mongodb мангуст

У меня есть элементы в коллекции, которые проходят через этот агрегат, чтобы найти их со средней оценкой и найти их, когда они еще не были прокомментированы / оценены.

Это работает, но каждый раз, когда я обновляю страницу сейчас, он создает дубликат, отображаемый в ng-repeat каждого элемента в коллекции бурбона. Фактическое количество предметов в коллекции бурбона не меняется. Как мне остановить это? СЕРВЕРНАЯ СТОРОНА: схема бурбона:

'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;

схема комментария/рейтинга:

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

агрегатная функция:

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

Сторона клиента

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

контроллер:

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

                });
            };


        }]);
})();

Джейд:

.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

пытаюсь остановить дублирование элементов в коллекции бурбона при обновлении страницы.... Не уверен, что мне нужно реализовать здесь какой-то метод замены... немного застрял сейчас...

Вот что возвращает журнал консоли в функции контроллера/агрегата:

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 } ]

кажется, что каждый элемент в коллекции Bourbon дублируется всякий раз, когда эта функция запускается... , которая запускается при обновлении страницы как Bourbon.all в контроллере angular.

это бурбон в коллекции, до того, как он пройдет через агрегат:

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

обновлен Джейд с треком от:

.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

это позволяет отображать элементы при первой загрузке, но при любом обновлении/перезагрузке теперь я получаю эту ошибку:

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://aries-wineny.com/wp-content/uploads/2014/09/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)

это элементы бурбона, возвращаемые в консоли браузера. все они имеют одинаковый bourbonId, начиная с индекса 0. Уникальный фильтр теперь возвращает 2 объекта бурбона (оригинал и один из дубликатов?) вместо всех из них...:

[Объект, Объект, Объект, Объект, Объект]0: Объект$$hashKey: "object:6"v: 0avgRating: 4blog: "fjkd;asdljfkld;ksdfj"bourbonId: "54c2aa5556267e0000b5618c", комментарии: Array[0] винокурня: "Вудфорд"местоположение: "Кентукки"название: "Вудфорд Резерв"фото: "http://aries-wineny.com/wp-content/uploads/2014/09/woodford-reserve.jpg"__proto: Object1: Object__v: 0avgRating: 4blog: «fjkd; asdljfkld; ksdfj» идентификатор бурбона: «54c2aa5556267e0000b5618c» комментарии: массив[0]вискикурня: «вудфорд»местоположение: «кентукки»название: «вудфорд заповедник»фото: «http://aries-wineny.com/wp-content/uploads/2014/09/woodford-reserve.jpg"proto: Object2: Object$$hashKey: "object:7"v: 0avgRating: 0blog: "fjkd;asdljfkld;ksdfj"bourbonId: "54c2aa5556267e0000b5618c"комментарии: Array[ 0]длина: 0__прото: А rray[0]вискикурня: "Вудфорд"местоположение: "Кентукки"название: "Вудфорд Резерв"фото: "http://aries-wineny.com/wp-content/uploads/2014/09/woodford-backup.jpg"прототип: Object3 : Object__v: 0avgRating: 0blog: "fjkd;asdljfkld;ksdfj"bourbonId: "54c2aa5556267e0000b5618c"комментарии: Array[0]length: 0__proto__: Array[0]вискикурня: "woodford"местоположение: "kentucky"название: "woodford Reserve"photo : "http://aries-wineny.com/wp-content/uploads/2014/09/woodford-reserve.jpg"proto: Object4: Object__v: 0avgRating: 0blog: "fjkd;asdljfkld;ksdfj"bourbonId: "54c2aa5556267e0000b5618c"комментарии: Массив[0]длина: 0__proto__: Массив[0]вискикурня: "вудфорд"местоположение: "кентукки"название: "вудфорд заповедник"фото: "http://aries-wineny.com/wp-content/uploads/2014/09/woodford-reserve.jpg"proto: Objectlength: 5__proto__: Array[0]


Я думаю, что я сузил это до проблемы на стороне сервера, в контроллере/агрегате, указанном выше. Мне нужно найти способ заменить обновленные документы, а не создавать новый каждый раз, когда Bourbon.all вызывается/запускается на стороне клиента/браузере... пытаюсь решить эту проблему сейчас. Любые советы, высоко ценится.


person NoobSter    schedule 23.01.2015    source источник
comment
add ng-repeat='bourbon in bourbons track by id id будет вашим уникальным ключом объекта.   -  person Pankaj Parkar    schedule 23.01.2015
comment
спасибо. Я просто изучал это: bennadel.com/blog/   -  person NoobSter    schedule 23.01.2015
comment
используйте ng-repeat='bourbon in bourbons track by bourbon.bourbonId' должно работать   -  person Pankaj Parkar    schedule 24.01.2015
comment
Я попробую еще раз, но это то, что я делаю, чтобы получить ошибку в комментарии выше. он отображается в первый раз, затем при обновлении / перезагрузке выдает повторяющуюся ошибку.   -  person NoobSter    schedule 24.01.2015
comment
попробуй в последний раз ng-repeat='bourbon in bourbons track by $index'   -  person Pankaj Parkar    schedule 24.01.2015
comment
он не возвращает ошибку, но дублирование все еще происходит. Начинаю думать, что это может быть больше на стороне сервера.   -  person NoobSter    schedule 24.01.2015
comment
похоже, что сервер возвращает повторяющиеся данные ... не могли бы вы проверить сетевую панель инструмента разработчика Chrome. сервер возвращает это или нет?   -  person Pankaj Parkar    schedule 24.01.2015
comment
это проблема на стороне сервера?   -  person Pankaj Parkar    schedule 24.01.2015
comment
ищу под сетью, чтобы увидеть, могу ли я ее найти. Видите ли вы что-нибудь на моем серверном контроллере/агрегате, что может вызвать дублирование?   -  person NoobSter    schedule 24.01.2015
comment
это все, что я вижу в «заголовках ответа» на «получить» для функции Bourbon.all: cache-control:no-cache Connection:keep-alive content-encoding:gzip content-type:application/json; charset = utf-8 Дата: пятница, 23 января 2015 г. 21:34:52 GMT   -  person NoobSter    schedule 24.01.2015
comment
вы смотрите на вкладку заголовков, попробуйте посмотреть рядом с вкладкой..Preview или Response   -  person Pankaj Parkar    schedule 24.01.2015
comment
о верно. вот что я получаю в «ответе»: {бурбоны: [{имя: вудфордский заповедник, местонахождение: кентукки, ликеро-водочный завод: вудфорд, блог: fjkd; asdljfkld; ksdfj, __v: 0, комментарии: [], фото: aries-wineny.com /wp-content/uploads/2014/09/},{имя:вудфордский заповедник,местоположение:Кентукки,вискикурня:вудфорд,блог:fjkd;asdljfkld;ksdfj,__v:0,комментарии:[],фото: ариев-wineny. com/wp-content/uploads/2014/09/},   -  person NoobSter    schedule 24.01.2015
comment
Вот какая проблема на стороне сервера... вы можете попробовать мое решение... Я добавил ответ   -  person Pankaj Parkar    schedule 24.01.2015
comment
спасибо попробую. Может быть хорошим патчем, пока я не выясню, что происходит на стороне сервера.   -  person NoobSter    schedule 24.01.2015
comment
findAndModify вместо find   -  person Pankaj Parkar    schedule 24.01.2015


Ответы (2)


Кажется, это просто случай слишком буквального понимания примера. Вы получаете дублированный вывод по каждому запросу, потому что именно так определяется область действия хранилища, из которого поступают результаты.

Итак, вместо этого:

'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){

Скорее сделайте так:

'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){
person Neil Lunn    schedule 24.01.2015
comment
не уверен, смеяться или плакать.. Спасибо. путешествие продолжается. - person NoobSter; 24.01.2015

Кажется, это проблема со стороны сервера. Добавление трека по $index решит проблему.

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

Но дело в том, что он покажет повторяющиеся записи.

Лучше использовать AngularUI angular.unique фильтр

Сначала добавьте JS из ссылки, а затем добавьте модуль ui.filters внутри зависимости приложения.

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

Надеюсь, это решит вашу проблему.

Спасибо.

person Pankaj Parkar    schedule 23.01.2015
comment
я пробовал это, и я пробовал findAndModify .. пока ничего не работает. findAndModify дает мне метод не может найти findAndModify , но, насколько я понимаю из документации, он должен быть встроен в mongoose/mongodb.. - person NoobSter; 24.01.2015
comment
этот уникальный фильтр должен работать в любом случае. Вы включили js github.com/angular-ui/angular-ui-OLDREPO/blob/master/modules/ и соответствующий модуль внутри вашего приложения 'ui.filters' - person Pankaj Parkar; 24.01.2015
comment
Я использовал angular-ui-utils, который, кажется, включает уникальный фильтр. Я попробую это вместо этого. - person NoobSter; 24.01.2015
comment
хорошо, я вынул $index, и уникальный фильтр, кажется, работает... отчасти... все еще допуская 1 дубликат... - person NoobSter; 24.01.2015
comment
каждый раз, когда я обновляюсь, он добавляет дубликат объекта, в настоящее время есть 4 дубликата. С уникальным фильтром показывает оригинал и 1 из дубликатов вместо всех дубликатов, как было раньше. Когда я перезагружаю сервер, он стирает дубликаты... так что, я думаю, они помещаются в хранилище браузера...? не уверен, как это работает.. - person NoobSter; 24.01.2015
comment
rachufour.org/alyce/2015/01/04/ кое-что, связанное с вашей проблемой - person Pankaj Parkar; 24.01.2015
comment
уникальный фильтр работает нормально.. может быть, объект, который он показывает, имеет другой 'bourbonId' - person Pankaj Parkar; 24.01.2015
comment
Я думаю, что есть какая-то проблема с БД.. вы можете отметить мое решение.. если оно вам помогло. - person Pankaj Parkar; 24.01.2015