0

I’m having some trouble with getting the value of an object in my array when the value is determined by a function instead of hard coded. In this example, I want to either iterate through the array to console.log the value of my “stats” object and not return the function I have there OR add to the existing function on each object in my array to console.log the value and again, not the function itself.

Here, my function returns the value in a text box as the value of the object “stats” in my array. Every time I try it either returns the function itself as the value or returns a “null” or only returns the value of the first object in my array.

Can someone please tell me what I am missing?

Thanks.

Here is my (full HTML) sample code with the "options" I have tried.

let users = [{
    name: "bob",
    stats: function() {
      return document.getElementById('option1').value;
    },
    code: "A1"
  },
  {
    name: "john",
    stats: function() {
      return document.getElementById('option2').value;
    },
    code: "A2"
  },
  {
    name: "karen",
    stats: function() {
      return document.getElementById('option3').value;
    },
    code: "A1"
  }
]

/* Option 1 */
console.log('firstRun');
users.forEach((user) => console.log(user.stats));

/* Option 2 */
console.log('secondRun');
for (let user of users) {
  console.log(user.stats)
}

/* Option 3 */
console.log('thirdRun');
var myArray = users.length;
for (i = 0; i < myArray; i++) {
  console.log(myArray.stats)
}
<h2>Simple Object/Array Step Through</h2>

<input type="text" id="option1" value="box1">
<input type="text" id="option2" value="box2">
<input type="text" id="option3" value="box3">
Olian04
  • 4,754
  • 2
  • 23
  • 46
Aubrey Love
  • 552
  • 4
  • 9
  • 3
    You have to use `stats()` to run the function. `stats` just returns the function itself. – Kvothe Aug 03 '20 at 21:57
  • 2
    DRY! Why not just storing the `id` of each element instead of the whole function again and again. Just store the id, and use it as a parameter – B001ᛦ Aug 03 '20 at 21:57
  • 1
    Does this answer your question? [Difference between this.function and this.function()](https://stackoverflow.com/questions/27408295/difference-between-this-function-and-this-function) – John Montgomery Aug 03 '20 at 21:58
  • 1
    Also, see [Why does jQuery or a DOM method such as `getElementById` not find the element?](https://stackoverflow.com/q/14028959/4642212). You’re not waiting for the DOM to be loaded. None of the options could ever result in `null`, but they might throw the _“`TypeError`: cannot read property '`value`' of `null`”_. – Sebastian Simon Aug 03 '20 at 22:01
  • 1
    Be careful with that last loop `for (i = 0; i < myArray; i++)` is missing the `let` keyword. This means you are modifying the global `i`. The for-loop should also use `myArray[i].stats` (not `myArray.stats`) the array itself doesn't have a `stats` property. – 3limin4t0r Aug 03 '20 at 22:40

1 Answers1

1

Try this,

Call the function and fix your Option 3 loop myArray is actually users.length redefined.

let users = [{
    name: "bob",
    stats: () => document.getElementById('option1').value,
    code: "A1"
  },
  {
    name: "john",
    stats: () => document.getElementById('option2').value,
    code: "A2"
  },
  {
    name: "karen",
    stats: () => document.getElementById('option3').value,
    code: "A1"
  },
  {
    name: "steve",
    stats: () => document.getElementById('option4').value,
    code: "A5"
  }
]

/* Option 1 */
console.log('firstRun');
users.forEach(user => console.log(user.stats()));

/* Option 2 */
console.log('secondRun');
for (let user of users) {
  console.log(user.stats())
}

/* Option 3 */
console.log('thirdRun');
for (let i in users) {
  console.log(users[i].stats())
}

/* Option 4 */
console.log('forthRun');
for (let i = 0; i < users.length; i++) {
  console.log(users[i].stats())
}
<h2>Simple Object/Array Step Through</h2>

<input type="text" id="option1" value="box1">
<input type="text" id="option2" value="box2">
<input type="text" id="option3" value="box3">
<input type="text" id="option4" value="box4">

Seems abit odd to try multiple ways to loop over an array, so I added for..in for continuity

Lawrence Cherone
  • 41,907
  • 7
  • 51
  • 92
  • FWIW storing the length value for a for loop is a well-known micro-optimization that does speed up your code a bit. So removing `myArray` is not **fixing** the code but de-optimizing it. TBH I personally don't think most people need it since the savings are tiny but if you're processing millions of objects then it's an easy first-step in optimizing your code. Property access in javascript like `array.length` have some cost and you will see the `myArray` trick used a lot in highly optimized libraries like jQuery – slebetman Aug 03 '20 at 22:55
  • I tried the "code snippet" and it ran fine on this webpage. However, when I copied it to my HTML document, it keeps giving me an "uncaught error...." I did a copy/paste of your entire script code and HTML code just to make sure I wasn't getting a typo and it still produces the same error. Is there something in your code snippet I am missing? Thanks. – Aubrey Love Aug 04 '20 at 15:18
  • what browser and version are you using? – Lawrence Cherone Aug 04 '20 at 15:20
  • Google Chrome Version 84.0.4147.105 (Official Build) (64-bit) – Aubrey Love Aug 04 '20 at 15:26
  • If I remove all the ".value" in the array, then it runs the code but returns all "null" values. Obviously. I also tried to using ".innerHTML", but it also returns the error "Uncaught TypeError: Cannot read property 'value' of null. – Aubrey Love Aug 04 '20 at 15:45
  • the js needs to be placed after the html else wrap in an document.onload, @user4642212 has mentioned that in a comment – Lawrence Cherone Aug 04 '20 at 15:46
  • Okay, my brain-fart. I was putting the script page reference in the "head" instead of at the closing "body" tag. It's working now, Thanks for you assistance. Much appreciated. – Aubrey Love Aug 04 '20 at 15:58