0

I know there are some related posts and I have gone through them, but I have not been able to make my code work. The provided code is a simplified portion of a larger code base. As you can see below, there is a for loop through the array of JSON objects, and inside that for loop there is a function call that returns the Y coordinates. We decide what to return, based on a property (flag) from each JSON object in the array - "invert". It's an angularJS code, built upon angular-nvd3 charts, but I believe the issue here is in how JS generally handles loops and nested function calls.

Can I directly access the "invert" property of array items from the function body within each iteration or is it technically impossible?

var listOfOptions = [];

for (var j = 0; j < arrayOfJSONObjects.length; j++) { 
// assuming arrayOfJSONObjects has only two elements,
// when the loop finishes, j is going to be equal to 2 


    var options = {
         isInverted: arrayOfJSONObjects[j].invert, 
         // here all works well, we get the "invert" 
         // property from each loop step into each "options" object

         chart: {
             type: 'lineChart',
             height: arrayOfJSONObjects[j].height,

             y: function (d) {
                   console.log(j); 
                   // here there is already an issue, j 
                   // always appears as 2, meaning that 
                   // the loop has already completed

                   console.log(arrayOfJSONObjects[j].invert); 
                   // same issue here, it always outputs the
                   // invert property of the last (second) element in 
                   // the list - arrayOfJSONObjects[1].invert

                   if (arrayOfJSONObjects[j].invert == 1) {
                        return (d.y * (-1)); 
                   }
                   else { 
                        return d.y;
                   } 
               } // end y

           } // end chart

       }; // end options


        listOfOptions.push(options);

 } // end for
user2217057
  • 237
  • 3
  • 17
  • Simplest solution is `let j = 0;` instead of `var j = 0;`. A solution with more compatibility if you need to support old engines and aren't using a transpiler is: `arrayOfJSONObjects.forEach( function ( obj ) { var options = { isInverted: obj.invert, ... } );` – Paul May 17 '18 at 21:24
  • Also just a note, `arrayOfJSONObjects` is a very bad variable name. Firstly, it is an array of plain old JavaScript objects that has nothing to do with JSON anyway. There is no JSON in that array. Secondly, even if it was an array of JSON, a variable name should describe what information it conveys not the structure of that information. – Paul May 17 '18 at 21:27
  • I agree with you comments on naming, that's what I refactored into conditional names just for posting purposes. – user2217057 May 17 '18 at 21:35
  • I had tried "let", but it did not work either. – user2217057 May 17 '18 at 21:36
  • `let` should work. Try it again and check the `console.log(j);`. – Paul May 17 '18 at 21:37
  • It did work, actually, appreciate you insisting on double checking. I changed to let and cleared the browser cache this time. Then it worked. Do you want to put a quick response, so that I mark it as answer? – user2217057 May 17 '18 at 21:54
  • I can't post an answer since I linked it to another question, but you can see the accepted answer there shows `let` as one of the possible solution (Update 2): https://stackoverflow.com/a/750506/772035 . Anyway, I'm glad you were able to get it to work :) – Paul May 17 '18 at 22:01

0 Answers0