0

EDIT: There is a couple of threads suggested as an answer but none of the ideas on either of the threads quite worked. And I tried all of them.

MAJOR THANK YOU: User Eazy solved this one with his further comment in his suggestion. It turned out that the correct way to do this was to put the whole paresInt math in parenthesis:

List += "" + list[i].team + "" + (parseInt(list[i].wins) + parseInt(list[i].ties) + parseInt(list[i].lost)) ""

The original question:

So I'm making a js code to print a table from a database. The database contains a soccer league table with team names, games won, tied and lost. As I print the table to HTML I want to do the math to calculate games played and total points as the information is not provided by the database.

The strangest thing is that if I multiply (*) values from the table, it works. If I subtract (-) or divide (/) the numbers, it works. But if I try to add the numbers together with +, the code treats the numbers as strings and just writes the next to each other. I've run to this problem before and I puzzled. The solution is probably a very obvious one but I just can't figure it out.

If a team has won 23 games, tied 7 times and lost 3 times, that adds up to 33 games played. So if I do the math:

List += "<tr><td>" + list[i].team + "</td><td>" + 
list[i].wins + list[i].ties + list[i].lost + "</td></tr>"

It returns 2373

If I use a different operator like multiplication:

List += "<tr><td>" + list[i].team + "</td><td>" + 
list[i].wins * list[i].ties * list[i].lost + "</td></tr>"

It returns 483 wichs is correctly calculated so the items clearly are not strings. And as I said, the code works with all other operators except the +. Why is this?

Cœur
  • 37,241
  • 25
  • 195
  • 267
  • 2
    Neither of these versions should work. You have a `)` without a matching `(` and you are missing the `+` after your .lost – Taplar Jun 18 '18 at 20:15
  • 2
    "the code treats the numbers as strings". No, they are indeed strings and all other operations force conversion to number – juvian Jun 18 '18 at 20:16
  • Oh sorry, the missing + and the lone ) (I accidentally left it there after trying the pareInt() -option) are typos in the post, not in the actual code. – Ville Johannes Pajala Jun 18 '18 at 20:49

3 Answers3

2

JavaScript is extremely weakly typed. It assumes everything that could be a string is a string, so it will concatenate the numbers because addition is defined for strings. Multiplication, division, and subtraction are not defined for strings, so the compiler will first check whether integer operation is possible.

You probably want to use the parseInt() function to guarantee the numbers are processed correctly.

  • I tried parseInt(list[i].wins) + etc and it didn't have any effect. But that is very unsettling that this is a language feature :) – Ville Johannes Pajala Jun 18 '18 at 20:34
  • It's a well-known drawback of weak typing, but its main advantage is the reduction in time taken to write code in most cases. In situations where there's no ambiguity about the variable, you don't have to think about what type to make it. The trade-off is edge cases like this where you have to explicitly state that you want this to be treated as an integer – Brandon Wyatt Jun 18 '18 at 22:48
  • Okey, maybe it is a good trade off after all – Ville Johannes Pajala Jun 19 '18 at 04:44
1

An alternative to parseInt() that @Brandon Wyatt told you is to put your variables inside parentheses.

const list = [
    {team: 'Team 1', wins: 5, ties: 3, lost: 2},
  {team: 'Team 2', wins: 2, ties: 3, lost: 5}
]

let content = "";
for (let i = 0; i < list.length; i++) {
    content += "<tr><td>" + list[i].team + "</td><td>" + (list[i].wins + list[i].ties + list[i].lost) + "</td></tr>";
}


document.getElementById("teams").innerHTML = content;

jsfiddle with this solution: https://jsfiddle.net/j7nfqvmr/21/

gbarzagli
  • 71
  • 5
  • The data is coming from SQL database so it comes in a form of ('Team1 ',23,7,3), (Team2,16,10,7) etc. And I already use the same for loop and code structure. This is so odd. – Ville Johannes Pajala Jun 18 '18 at 20:45
0

I had advise you use parseInt() to force the the returned value to an Integer.

So your code can look like this:

List += "<tr><td>" + list[i].team + "</td><td>" + 
parseInt(list[i].wins) + parseInt(list[i].ties) + parseInt(list[i].lost) "</td></tr>"
Eazy
  • 133
  • 11
  • I thought of that too and already tried it, it had no effect whatsoever - it still treats them as strings. I even doublechecked and tried it again with no luck. – Ville Johannes Pajala Jun 18 '18 at 20:39
  • Okay, I advice you cast them with parenthesis `()`, `List += "" + list[i].team + "" + (parseInt(list[i].wins) + parseInt(list[i].ties) + parseInt(list[i].lost)) ""` – Eazy Jun 18 '18 at 20:58
  • I believe with that, the mathematical computation will be calculated first, taking the parenthesis `()` as a precedence. – Eazy Jun 18 '18 at 21:01
  • This worked! Thank's Man! I tried all possible variations from the suggested threads but none of the tricks worked. You saved my day :) – Ville Johannes Pajala Jun 18 '18 at 21:15
  • I'm happy I was able to assist you :) – Eazy Jun 18 '18 at 21:53