Search code examples
javascriptbackbone.jsfetchjasny-bootstrap

Backbone fetch removes and readds the same models every time


I have a 'business' collection which I pass to several views.

When I run this.business.fetch(), the models returned are exactly the same but the events 'add' and 'remove' get triggered because the collection thinks the models returned are new so it removes the 'old' and adds the 'new' models. The only difference i can see between the models is the cid.

Why does the fetch think the collection has changed? even though it hasn't?

This is my code:

router.js
var Router = Backbone.Router.extend({
routes: {
    "home": "home",
}
initialize: function() {
  this.business = new Business();
  this.business.fetch();
},
home: function() {
  var homepageView = new HomePageView({business: this.business});
},

.

HomePageView.js
var HomePageView = Backbone.View.extend({
initialize: function (options) {
  this.business = options.business;
  this.listenTo(this.business, "add",    this.onBusinessAdd);
  this.listenTo(this.business, "remove", this.onBusinessRemove);
  this.listenTo(this.business, "change", this.onBusinessRemove);
  this.business.fetch();
},
onBusinessAdd: function(model) {
  console.log(model);
},
onBusinessRemove() & onBusinessChange() are the same as onBusinessAdd()

.

collection/business.js
var BusinessCollection = BaseCollection.extend({
initialize : function() {
  this.urlRoot = this.path + 'business/me';
  this.url = this.path + 'business/me';
  this.model = BusinessModel;
}

.

I have a different collection called items, and that fetches perfectly. But for some reason, when i run business.fetch() on the first fetch, it adds 2 businesses cid 19 & 20, then on the second fetch, it deletes cid 19 & 20 and adds cid 23 & 24 even though they are the same

i get the following in my console:

first fetch: (router.js)
"onBusinessAdd"
n {cid: "c19", attributes: Object, collection: n, _changing: false, _previousAttributes: Object…}
n {cid: "c20", attributes: Object, collection: n, _changing: false, _previousAttributes: Object…}

second fetch: (homepageview.js)
"onBusinessRemove"
n {cid: "c19", attributes: Object, collection: n, _changing: false, _previousAttributes: Object…}
n {cid: "c20", attributes: Object, collection: n, _changing: false, _previousAttributes: Object…}
"onBusinessAdd"
n {cid: "c23", attributes: Object, collection: n, _changing: false, _previousAttributes: Object…}
n {cid: "c24", attributes: Object, collection: n, _changing: false, _previousAttributes: Object…}

. The attributes of "c19" == "c23" and "c20" == "c24"

Object {_id: "567b6997a58029fc087b1716", hasLogo: false, approved: false, postcode: "2131", suburb: "1231321"…}
__v : 0
_id : "567b6997a58029fc087b1716"
approved : false
created : 1458794097462
email : "[email protected]"
hasLogo : false
name : "afsaf"
phone : "0123456789"
postcode : "2131"
reservationlist : Array[1]
settingsSchema : Array[1]
staff : Array[1]
street : "123132"
suburb : "1231321"
waitlist : Array[1]

.

.

this causes a problem for me as my navbar render() gets called every time the onBusinessAdd function gets called and for some reason the jasny-bootstrap navbar bugs out and clones itself on every render() which causes lag. (i'll have to look into that after i fix this problem first)


Solution

  • Your response doesn't seem to have an id attribute, but has an _id property instead.

    either you should sent it is id, or you should inform backbone to use _id for tracking models using the idAttribute option.

    The example in official docs has an _id as well:

    var Meal = Backbone.Model.extend({
      idAttribute: "_id"
    });