what is the best way to guard ES6's for ... of loop?
for (let bar of foo.bars) {
baz = await quix(bar)
}
what if bars is undefined? It throws
TypeError: undefined is not iterable!
A simple
if (foo.bars) {
// ..
}
is the way to do it?
what is the best way to guard ES6's for ... of loop?
for (let bar of foo.bars) {
baz = await quix(bar)
}
what if bars is undefined? It throws
TypeError: undefined is not iterable!
A simple
if (foo.bars) {
// ..
}
is the way to do it?
Yes, make sure in some way that foo.bars
is not undefined before the loop. How to do that depends on your actual use case of course.
If you have some kind of nullable field in your object, an if
test would be the cleanest way indeed. A less obvious alternative is iterating an empty collection as a defaulting value:
for (let bar of foo.bars || []) {
baz = await quix(bar)
}
However, the best practice probably would be to have the empty collection instead of null
(or undefined
) as the property value right away.
A complete guard to protect against any possible data that might cause an exception at the beginning of the for/of
loop would have to test three things:
foo
existsfoo.bar
existsfoo.bar
is iterableThere is no super clean way of testing all three:
if (foo && foo.bar && typeof foo.bar[Symbol.iterator] === "function") {
for (let bar of foo.bar) {
baz = await quix(bar);
}
}
More info on testing to see if something is an iterable here: What is the technical definition of a Javascript iterable and how do you test for it?
You could, of course, just use a try/catch around it and catch any exception rather than pre-testing for it (which you may need anyway to handle rejections in the await
).