0

I am trying to GET total order prices (in USD) in an object array and sum the total. Instead of summing the array, the order totals are concatenated. How do I force addition instead of concatenation?

<body>
<p id=sales></p>
<script>
var sales, i, x = "";

sales = {"orders": [{"total_price_usd": "92.05"}, {"total_price_usd": "14.90"}, {"total_price_usd": "17.90"}, {"total_price_usd": "14.90"}]}

for (i in sales.orders) {
    x += sales.orders[i].total_price_usd + ', ';
}
var numbers = [x];
function getSum(total, num) {
    return parseFloat(total) + parseFloat(num);
}
document.getElementById('sales').innerHTML = '$' + numbers.reduce(getSum);
</script>
</body>
4
  • 4
    That's not JSON. "JSON is a textual, language-indepedent data-exchange format, much like XML, CSV or YAML." - What is the difference between JSON and Object Literal Notation? Commented Feb 16, 2018 at 16:37
  • 1
    numbers just contains a long, comma-separated string, how do you expect to be able to parse it as a number? Commented Feb 16, 2018 at 16:39
  • 1. The value of total_price_usd is a string. 2. If you want to sum numbers why do you then add ', '? Commented Feb 16, 2018 at 16:39
  • The server returns the total prices as strings. Commented Feb 17, 2018 at 15:43

4 Answers 4

1

This line doesn't create an array of numbers:

var numbers = [x];

It's just creating an array with one element, a string, as if you'd written:

var numbers = ["92.05, 14.90, 17.90, 14.90"]

Then when you call numbers.reduce(), it just processes the first number in the string, it doesn't loop over them. Using a variable that contains a string doesn't cause it to parsed as if it were Javascript source.

You should do:

var numbers = []
for (var i = 0; i < sales.order.length; i++) {
    numbers.push(parseFloat(sales.order[i].total_price_usd));
}

Or you can just do the addition in this loop, instead of using reduce() later:

var total = 0;
for (var i = 0; i < sales.order.length; i++) {
    total += parseFloat(sales.order[i].total_price_usd);
}
Sign up to request clarification or add additional context in comments.

1 Comment

Sounds like a micro-optimization that's unlikely to be significant in most programs.
0

Using parseFloat() on the variables and initialising x to 0 should help

var sales, i, x = 0;

sales = {"orders": [{"total_price_usd": "92.05"}, {"total_price_usd": "14.90"}, {"total_price_usd": "17.90"}, {"total_price_usd": "14.90"}]}

for (i in sales.orders) {
    x += parseFloat(sales.orders[i].total_price_usd);
}
var numbers = [x];
function getSum(total, num) {
    return parseFloat(total) + parseFloat(num);
}
document.getElementById('sales').innerHTML = '$' + numbers.reduce(getSum);
<div id="sales"></div>

Do note that adding floating point numbers in Javascript can lead to some pretty common discrepancies. Is floating point math broken?

1 Comment

The numbers array is completely pointless, as is the call to .reduce()
0
  • You can access directly to array sales.orders
  • Within function getSum get the price in USD num.total_price_usd

var sales = {"orders": [{"total_price_usd": "92.05"}, {"total_price_usd": "14.90"}, {"total_price_usd": "17.90"}, {"total_price_usd": "14.90"}]};


//------------- You need to verify this logic
var i, x = ""

// You're creating an array as follow: ["1, 2, 4, 5"].
for (i in sales.orders) {
    x += sales.orders[i].total_price_usd + ', ';
}
var numbers = [x];
//-------------------------------------------

function getSum(total, num) {
    return parseFloat(total) + parseFloat(num.total_price_usd);
}

document.getElementById('sales').innerHTML = '$' + sales.orders.reduce(getSum, 0);
<p id=sales></p>

2 Comments

Why did you keep the first loop with x and the numbers variable that you're not using any more?
@Barmar to illustrate the problem that OP is facing.
0

Just use reduce and the Number constructor:

sales = {"orders": [{"total_price_usd": "92.05"}, {"total_price_usd": "14.90"}, {"total_price_usd": "17.90"}, {"total_price_usd": "14.90"}]}

const total = sales.orders.reduce(
  (total, order) => total + Number(order.total_price_usd), 
  0
)

console.log(total)

parseFloat and the unary + will also work, as others point out. I think Number is the most readable, but your mileage may vary.

4 Comments

How does this solve the real problem? It just seems like a style change, but the bug still exists.
What real problem do you see? I start with the initial data and return the expected total. I suppose I don't explain what's wrong with the original, but it seemed like the question was about getting addition instead of concatenation. I'll add a snippet.
Oh, didn't see that you changed the variable you're looping over, I thought you just changed parseFloat to Number.
Oh, that makes sense. Yes, that wouldn't do much. ;-)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.