LoveAndHappiness LoveAndHappiness - 1 month ago 7
Javascript Question

PolymerJS: How to Update all Items in an Array with set() and a forEach loop properly

I have an array that looks like this:

items: [
{title: 'First Title', completed: false},
{title: 'Second Title', completed: false},
{title: 'Third Title', completed: false}
];


I'd like to set each
item
to
true
. For this I have a button that fires an event on-tap that executes the following code snippets.

The Polymer team sets the Boolean value with a
for
loop:

for (var i = 0; i < this.items.length; ++i) {
this.set(['items', i, 'completed'], true);
}


I personally prefer to use a forEach loop, because I'd like to compare Polymer to different frameworks and it happens to happen that I am using
forEach
loops in similar cases.

My working solution:

var that = this;
this.items.forEach(function(item) {
var i = that.items.indexOf(item);

that.set('items.' + i + '.completed', true);
// or
// that.set(['items', i, 'completed'], true);
});


Specifically the part where I use
dots
to connect with
i
seems hacky to me.




Same code with Vue:

this.items.forEach(function(item) {
return item.completed = true;
});





The Polymer API states:


set(path, value, root) path (string|Array<(string|number)>)
Path to the value to read. The path may be specified as a string (e.g. foo.bar.baz) or an array of path parts (e.g. ['foo.bar', 'baz']). Note that bracketed expressions are not supported; string-based path parts must be separated by dots. Note that when dereferencing array indicies, the index may be used as a dotted part directly (e.g. users.12.name or ['users', 12, 'name']).
value *
Value to set at the specified path.
root Object=
Root object from which the path is evaluated.





Question:

Because the part where I use an index seems just a bit hacky for a lack of a better term, I wonder, if there is a more convenient way to use a forEach loop in Polymer to update all items in the Array.

Thanks.

Answer

forEach's callback function can have a second parameter that refers to the current index. This also goes for Array's map, every, some, and filter methods.

ES5 Version

this.items.forEach(function(item, index) {
  this.set('items.'+index+'.completed', true);
}.bind(this));

ES6 Version

this.items.forEach((item, index) => this.set(`items.${index}.completed`, true));

Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Parameters

Comments