Astw41
Astw41

Reputation: 392

Add multiple variables in a JS loop

I have multiple inputs (class .fat-calc1 to .fat-calc24) and a result place (class fat-result). I want to make a loop that adds inputs (.fat-calc1 + .fat-calc2 + ... + .fat-calc24) and displays that in the result div.

<div class='fat-calc-col'>
  <input type='number' name='fat-calc1"' class='fat-calc fat-calc1'>
  <input type='number' name='fat-calc2"' class='fat-calc fat-calc2'>
  <input type='number' name='fat-calc2"' class='fat-calc fat-calc2'>
  ...
  <div class='calc-result fat-result'></div>
</div>
$(".fat-calc-col").children().on('input', function(e){

    var fat = [];
    let result = "";
    
    for (let x = 1; x <= 24; x++) {
        fat[x] = parseFloat($(".fat-calc" + x).val());
        fat[x] = fat[x] ? fat[x] : 0;
        result += fat[x];
    }

    $(".fat-result").text(result);
    
});

When you type 1 into fat-calc1 and 3 into fat-calc2 the result it not 4, but 130000000000000000000000. I was trying to add parseFloat to basically everything I could, but it didn't work. Why does that happen? How to fix it?

Upvotes: 1

Views: 84

Answers (3)

Lakshya Raj
Lakshya Raj

Reputation: 1775

The reason that 130000000000000000000000 is your output instead of simply 4 is because you are concatenating strings instead of adding integers.

What you think your code is doing is 1 + 3 + 0 + 0 + 0 + ... + 0 = 4, but in reality, you're doing "" + 1 + 3 + 0 + 0 + ... + 0. Since a string is starting the chain, the final result will be a string. It evaluates like this:

"" + 1 + 3 + 0 + 0 + ... + 0
"1" + 3 + 0 + 0 + ... + 0
"13" + 0 + 0 + ... + 0
"130" + 0 + 0 + ... + 0
"1300" + 0 + 0 + ... + 0
"130000000000000000000000"

One way you can fix it is to make sure result = 0 at the start. Try this code:

$(".fat-calc-col").children().on('input', function(e){

    var fat = [];
    let result = 0; // 0, not ""
    
    for (let x = 1; x <= 24; x++) {
        fat[x] = parseFloat($(".fat-calc" + x).val());
        fat[x] = fat[x] ? fat[x] : 0;
        result += fat[x];
    }

    $(".fat-result").text(result);
    
});

But this is also unnecessary. You can use the answer by Rory McCrossan for a better setup. Code here for reference (click to expand):

const $result = $('.fat-result');
const $inputs = $('.fat-calc').on('input', () => {
  const sum = $inputs.get().reduce((acc, el) => acc += +el.value, 0);
  $result.text(sum);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<input type="number" name="fat-calc1" class="fat-calc fat-calc1" />
<input type="number" name="fat-calc2" class="fat-calc fat-calc2" />
<input type="number" name="fat-calc2" class="fat-calc fat-calc2" />

<div class="calc-result fat-result"></div>

Upvotes: 2

Lukas249
Lukas249

Reputation: 2471

You add it all to string. Change it let result = ""; to it let result = 0;

Upvotes: 3

Rory McCrossan
Rory McCrossan

Reputation: 337560

If all you need to do is sum the values of the .fat-calc fields, then your code is far more complicated than it needs to be. You don't need an array, or a for loop over 24 arbitrary values.

To do what you require just need to loop through the input elements and sum their values. This can be done using reduce()

const $result = $('.fat-result');
const $inputs = $('.fat-calc').on('input', () => {
  const sum = $inputs.get().reduce((acc, el) => acc += +el.value, 0);
  $result.text(sum);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<input type="number" name="fat-calc1" class="fat-calc fat-calc1" />
<input type="number" name="fat-calc2" class="fat-calc fat-calc2" />
<input type="number" name="fat-calc2" class="fat-calc fat-calc2" />

<div class="calc-result fat-result"></div>

Upvotes: 3

Related Questions