backbone.js adding model to collection adds to all models in collection Code Answer

Hello Developer, Hope you guys are doing great. Today at Tutorial Guruji Official website, we are sharing the answer of backbone.js adding model to collection adds to all models in collection without wasting too much if your time.

The question is published on by Tutorial Guruji team.

Playing around with backbone.js, so far I’ve created models and collections for a deck of cards and two players. The problem is when I try move a card from the deck and add it to the player’s hand the card gets added to all players hands.

Here’s my offending code, hopefully a boffin will spot the mistake straight away:

//the first card goes to player1
var topCard = deck.at(0); //A of hearts
deck.remove(topCard);
var hand = players.at(0).get("hand");
hand.add(topCard);

//the second card goes to player2
topCard = deck.at(0); //2 of hearts
deck.remove(topCard);
hand = players.at(1).get("hand");
hand.add(topCard);

I end up with both players having both the “A of hearts” and the “2 of hearts” when it should be one card each.

full code:

var game = {};

game.Durak = Backbone.Model.extend({
  initialize : function() {
    var deck = new game.Deck();
    var player1 = new game.Player();
    player1.name = "Dave";

    var player2 = new game.Player();

    var players = new game.Players();
    players.add(player1);
    players.add(player2);

    deck.deal(players);

  }
});

game.Card = Backbone.Model.extend({
  defaults: {
    "suit" : "spades",
    "rank" : "A"
  }
});

game.Deck = Backbone.Collection.extend({
  model: game.Card,
  initialize : function() {
    var suits = ['hearts', 'spades', 'clubs', 'diamonds'],
    ranks = ['A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K'];

    _.each(suits, function(s) {
      _.each(ranks, function(r) {
        this.add({
          suit: s, 
          rank: r
        });
      }, this);
    }, this);
  },
  shuffle : function() {
    this.reset(_.shuffle(this.models));    
  },
  deal : function(players) {


    // this bit makes me sad!


    var topCard = this.at(0);
    this.remove(topCard);    
    var hand = players.at(0).get("hand");
    hand.add(topCard);

    topCard = this.at(0);
    this.remove(topCard);
    hand = players.at(1).get("hand");
    hand.add(topCard);
  }


  // that bit made me sad


});

game.Hand = Backbone.Collection.extend({
  model : game.Card
})

game.Player = Backbone.Model.extend({
  defaults : {
    name : "",
    hand : new game.Hand()
  }
});

game.Players = Backbone.Collection.extend({
  model: game.Player
});

new game.Durak();

Answer

Objects defined in a model’s defaults hash end shared between instances (see In what cases does defaults need to be a function? for a longer explanation)

Use a function to return your defaults values :

game.Player = Backbone.Model.extend({
    defaults: function() {
        return {
            name : "",
            hand : new game.Hand()
        };
    }
});

and a demo

var game = {};

game.Card = Backbone.Model.extend({
    defaults: {
        "suit" : "spades",
        "rank" : "A"
    }
});
game.Hand = Backbone.Collection.extend({
  model : game.Card
});

game.Player = Backbone.Model.extend({
    defaults: function() {
    return {
        hand: new game.Hand()
    };
  }
});
var players = new Backbone.Collection([
    new game.Player (),
    new game.Player ()
]);


var deck = new Backbone.Collection([
    {suit: "heart", rank: "A"}, {suit: "heart", rank: "2"}
]);
//the first card goes to player1
var topCard = deck.at(0); //A of hearts
deck.remove(topCard);
var hand1 = players.at(0).get("hand");
hand1.add(topCard);

//the second card goes to player2
topCard = deck.at(0); //2 of hearts
deck.remove(topCard);
var hand2 = players.at(1).get("hand");
hand2.add(topCard);

$('body').append("Hand 1 " + JSON.stringify(hand1.toJSON()));
$('body').append("Hand 2 " + JSON.stringify(hand2.toJSON()));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.3/backbone-min.js"></script>
We are here to answer your question about backbone.js adding model to collection adds to all models in collection - If you find the proper solution, please don't forgot to share this with your team members.

Related Posts

Tutorial Guruji