0

Inside my function/object I have

this.StatusMappings = [
   {
       Range: [Infinity*-1, 50],
       Color: 'red',
       Text: 'Just getting started - will require considerable time to complete.'
   },
   {
       Range: [50, 70],
       Color: 'yellow',
       Text: 'Incomplete - major gaps exist and completion will take some time.'
   },
   {
       Range : [70, 90],
       Color : 'yellgreen',
       Text : 'Partially completed - but some gaps remain which can be completed shortly.'
   },
   {
       Range: [90, Infinity],
       Color: 'green',
       Text: 'Fully completed - no additional work needed.'
   }
];

this.UpdateInfo = function ( $slider, newval )
{
    var color = this.StatusMappings.firstOrUndefined(function (map) {
        console.log("map.Range = "); console.log(map.Range);//TEST
        return map.Range[0] >= newval && map.Range[1] < newval;
    });
    $slider.closest('.slider').addClass(color);
}

and what's strange is that the first time UpdateInfo is called, everything goes as expected, whereas the second time I get

Uncaught TypeError: Cannot read property '0' of undefined

Because of my //TEST I see that it works the first time:

enter image description here

By the way, my helper function firstOrUndefined is

Array.prototype.firstOrUndefined = function ( unpred )
{
    for ( var i in this ) 
        if ( unpred(this[i]) )
            return this[i];          
}
Mina Gabriel
  • 23,150
  • 26
  • 96
  • 124
Subpar Web Dev
  • 3,210
  • 7
  • 21
  • 35
  • I believe this is the result of your `for-in` loop. The `for-in` loop accesses properties, methods and array members. My guess is that the this[i] member is probably a property or method of the Array.prototype instance and not an actual StatusMapping. – idream1nC0de Feb 19 '16 at 21:21

1 Answers1

4

When iterating over Arrays in JavaScript, it is never a good idea to use the for-in loop. It is always better to use a for loop to iterate over the Array. The for-in loop in JavaScript does not only access the Array members, it also accesses the Array prototype properties and methods. My testing in JSFiddle reveals that my hypothesis is correct, and the error is resulting from the fact that the Array.prototype.firstOrUndefined() extension is being passed into your unpred function, and that function does not have a property of 0. You can fix this by changing your for-in loop to a for loop.

Array.prototype.firstOrUndefined = function(unpred) {
  //Might be a good idea to validate unpred, too.
  if (typeof unpred === 'function') {
      for (var i = 0; i < this.length; i++)
        if (unpred(this[i]))
           return this[i];
  }
}

Please see the fiddle for a reference.

https://jsfiddle.net/7bdj6j92/2/

Further information on the reason why you shouldn't use the for-in loop with JavaScript Arrays: StackOverflow Answer

Community
  • 1
  • 1
idream1nC0de
  • 1,171
  • 5
  • 13