For Each Not For All

It wasn’t always like this, but in 2019, everyone loves Javascript.
At Hiring Hub, we certainly do, but it still maintains the ability
to frustrate occasionally.

One recent example of this was a bug we encountered on a few pages
but which only appeared on IE11. At first we assumed that this was
caused by an error in our transpilation process (our stack is rails
based but utilises a modern frontend layer including react, babel
and webpack via rails’ webpacker gem).

After much experimentation with webpack config, polyfills of
various kinds and even grepping through our production bundles, we
realised that the problem was not ultimately caused by
misconfiguration of our javascript transpiler.

Closer examination of the source code revealed that we were calling
in several places the Javascript forEach method (on
Array.prototype) – a method supported by all modern browsers,
including even IE11, and so not subject to transpilation by babel –
but on a NodeList, not an actual array. A NodeList is a type of
data structure returned by a call to
element.querySelectorAll(selectors), representing a list of DOM
nodes. It is similar to an array, and treated as such by most
browsers (and by developers!), but not, it turns out by IE11.

Our solution therefore was to rewrite the call to forEach to use
a utility method that uses a simple for loop under the hood – a
construct that is even supported by IE11 on NodeLists. Our method
looks something like this (stolen and modified from a post on CSS-Tricks):

   function forEach(array, callback, scope) {
     for (let index = 0; index < array.length; index += 1) {
       callback.call(scope, array[index], index);
     }
   }

And just like that, our broken pages were working on IE again.
We’re sorry we ever doubted you, babel :).

Originally published 10th April 2019