Rune
Rune

Reputation: 303

Underscore.js: Replace item in collection

I've been using underscore.js for a week now and I really like it. However, now I want to replace a single element in collection (vm.lists) with another element. I tried doing the following:

_.each(vm.lists, function (el) {
    if (el.id == list.id)
        el = list;
});

and:

var l = _.findWhere(vm.lists, { id: list.id });
l = list;

But none of them changes the actual item in the collection. How would I do this properly?

Upvotes: 0

Views: 2923

Answers (2)

Roman L
Roman L

Reputation: 3056

You got pretty close. The issue is that you are only replacing the local variables (el and l) pointing to the value, and this does not modify the initial list. A simpler example:

var list = [1, 2, 3];
var v = list[1];
v = 7; // v will now point to a new value, but list will stay intact [1, 2, 3]

Same with objects:

var olist = [{id: 1, v: 2}, {id: 4, v: 6}];
var obj = olist[0];
obj = {id: 8, v: 10}; // changes what obj points to, but does not affect olist[0]

var obj2 = olist[0];
obj2.v = 777; // olist[0] still points to the same object but the object is modified

olist[0] = {id: 8, v: 10}; // changes what olist[0] points to

So basically you have two options:

a) change vm.lists[index] so that it points to a new object. You would need to get the index of the object in the list and do vm.lists[index] = newObject;. Note that some underscore predicates also provide you the index _.each(list, function (el, index) {});.

b) change the object that vm.lists[index] points to, but you would need to copy fields manually. For example, if your object is represented as {id: id, values: [1, 2, 3], anotherField: data}, you could copy the fields:

//el.id = list.id; // don't need this as you were searching by id
el.values = list.values;
el.anotherField = list.anotherField;

IMO the first option would be cleaner.

Upvotes: 2

lloiser
lloiser

Reputation: 1191

there is no need for underscore here:

for (var i = 0, l = vm.lists.length; i < l; i++)
{
  var el = vm.lists[i];
  if (el.id == list.id) {
    vm.lists[i] = list;
    break; // stop the for loop
  }
}

Upvotes: 0

Related Questions