2

Why when I want to assign formatted number to variable it shows error?

var jsObject = new Object();
jsObject.number = 0;
for (i = 1; i <= 10; i++) {
  jsObject.number += 0.1;
  console.log((jsObject.number).toFixed(1)); // works and shows right numbers
  jsObject.number = (jsObject.number).toFixed(1); // TypeError: jsObject.number.toFixed is not a function
}
j08691
  • 204,283
  • 31
  • 260
  • 272
dt_
  • 95
  • 1
  • 10
  • 2
    Because it is a string after the first iteration. – epascarello Sep 10 '18 at 13:24
  • 2
    You’re overwriting the same `jsObject.number`; when you set `jsObject.number += 0.1` it’s a number; when you set `jsObject.number = (jsObject.number).toFixed(1)` it becomes a string. When you later set the same `.toFixed` line again, you don’t have a number anymore, but a string. – Sebastian Simon Sep 10 '18 at 13:26
  • Wow, couldn't imagine that toFixed converts to string. Fixed with parseFloat and temp variable. Thanks! – dt_ Sep 10 '18 at 13:30
  • 1
    Note that you can't *really* fix the decimal-place precision of a number, because numbers are represented in *binary* floating-point. When you convert the string result of `.toFixed()` back to a number, you'll get a value that's close to the decimal value the string represents but not necessarily identical. – Pointy Sep 10 '18 at 13:42

5 Answers5

4

Because .toFixed() retuns a string so you are replacing the number with a string. Simple logging will show you what is happening.

var jsObject = new Object();

jsObject.number = 0;

for(i = 1; i <= 10; i++) {

    jsObject.number += 0.1;
    console.log(i, "before", jsObject.number, typeof jsObject.number)
    jsObject.number = (jsObject.number).toFixed(1);            
    console.log(i, "after", jsObject.number, typeof jsObject.number)


}

The output will be:

1 before 0.1 number
1 after 0.1 string
2 before 0.10.1 string
"Uncaught TypeError: jsObject.number.toFixed is not a function",

JavaScript does not hold trailing zeros. So if you need them for output, it would be better to do it where you are outputting the number. Or the only other option would be to parseFloat Number it before you add to it.

jsObject.number = Number(jsObject.number) + 0.1;
jsObject.number = parseFloat(jsObject.number) + 0.1;
epascarello
  • 204,599
  • 20
  • 195
  • 236
0

toFixed returns a string and strings don't have a toFixed method. Update your for loop like this to get around that issue.

for (i = 1; i < 10; i++) {
    jsObject.number += 0.1;
    console.log((jsObject.number).toFixed(1));
    jsObject.number = parseFloat((jsObject.number).toFixed(1)); // <--
}
James Long
  • 4,629
  • 1
  • 20
  • 30
0

This method returns a string.

https://www.geeksforgeeks.org/javascript-tofixed-function/

Return Value: It returns a number in the string representation.

So the first time it works, but then it fails all the subsequent times and is no longer a number.

You could parse to a number, or force the conversion to a number ( by e.g. using multiplication ):

for(i = 1; i <= 10; i++) {

    jsObject.number += 0.1;

    console.log( (jsObject.number).toFixed(1) ); // works and shows right numbers

    jsObject.number = 1 * (jsObject.number).toFixed(1); // TypeError: jsObject.number.toFixed is not a 
} 
Menelaos
  • 23,508
  • 18
  • 90
  • 155
0

As stated in the comment, you are overwriting the number with a string representation of it (toFixed do this). So you have to re-convert your string into a number format. There are so many ways to do it correctly or not, I prefer to divide by 1 (or multiply)

var jsObject = new Object();
jsObject.number = 0;
for (i = 1; i <= 10; i++) {
  jsObject.number += 0.1;
  console.log((jsObject.number).toFixed(1)); // works and shows right numbers
  jsObject.number = (jsObject.number).toFixed(1) / 1; // TypeError: jsObject.number.toFixed is not a function
}
Matteo Gaggiano
  • 1,254
  • 15
  • 28
0

You need to convert the string returned from toFixed() into the correct data type.

toFixed() returns a string so on the second iteration, it's trying to call string.toFixed(), which doesn't exist since toFixed() is not for strings.

var jsObject = new Object();
jsObject.number = 0;

for(i = 1; i <= 10; i++) {
    jsObject.number += 0.1;
    console.log( jsObject.number.toFixed(1) );
    jsObject.number = Number.parseFloat(jsObject.number.toFixed(1)); 
}
Jimenemex
  • 3,104
  • 3
  • 24
  • 56