Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make Backbone.js Collection items Unique?

Say I have these Backbone.js Model:

var Truck = Backbone.Model.extend({});

var truck1 = new Truck();
var truck2 = new Truck();

truck1.set("brand", "Ford");
truck2.set("brand", "Toyota");
truck3.set("brand", "Honda");
truck4.set("brand", "Ford");

Then, let's say we have a Backbone.js Collection:

var TruckList = Backbone.Collection.extend({
  model: Truck,
  comparator: function(truck) {
     return truck.get("brand");
  };

});

I'm a car collector, so time to add each car to my collection:

Trucks = new TruckList();
Trucks.add(truck1);
Trucks.add(truck2);
Trucks.add(truck3);
Trucks.add(truck4);

Just focusing on the brand attribute, truck4 is a duplicate of truck1. I can't have duplicates in my Collection. I need my collection to have unique values.

My question is, How do I remove duplicate items from my Backbone.js Collection?

Should I use Underscore.js for this? If so, can someone please provide a working/runnable example of how to do this.

Assume the following:

1.Collection is not sorted

  1. Removal must be done on brand attribute value

  2. Ajax call to populate each instance of a Truck. This means when adding to a collection, you don't have access to the Truck properties.

like image 668
Keven Ruggish Avatar asked Jun 20 '11 20:06

Keven Ruggish


1 Answers

I would override the add method in your TruckList collection and use underscore to detect duplicates there and reject the duplicate. Something like.

TruckList.prototype.add = function(truck) {
    // Using isDupe routine from @Bill Eisenhauer's answer
    var isDupe = this.any(function(_truck) { 
        return _truck.get('brand') === truck.get('brand');
    });

    // Up to you either return false or throw an exception or silently ignore
    // NOTE: DEFAULT functionality of adding duplicate to collection is to IGNORE and RETURN. Returning false here is unexpected. ALSO, this doesn't support the merge: true flag.
    // Return result of prototype.add to ensure default functionality of .add is maintained. 
    return isDupe ? false : Backbone.Collection.prototype.add.call(this, truck);
}
like image 141
Peter Lyons Avatar answered Sep 26 '22 03:09

Peter Lyons