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. ;-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.