2

in my current source code textbox value is 1. when I try alert(isNaN(obj.text()) it returns false that is expected but after parseInt when I write alert(a); it returns NaN

minus.click(function () {
     var a = 1; if (!isNaN(obj.text())) a = parseInt(obj.text()); 
     if (a > 1) a -= 1; obj.text(a);
});

what is the problem?

Edit: this is the full code:

<input type="text" class="basket-txt" value="1" />


jQuery.fn.basket = function (options) {
    var defaults = {
    }
    options = jQuery.extend(defaults, options);
    this.each(function () {
        var $this = $(this);
        $this.height(32).css({ 'line-height': '32px', 'font-weight': 'bold', 'width':'40px', 'text-align':'center', });
        var tbl = $('<table border="0" style="border-spacing:0px;float:left;">').appendTo($this.parent());
        var tr1 = $('<tr>').appendTo(tbl);
        var plus = $('<div class="basket-plus">');
        $('<td>').append(plus).appendTo(tr1);
        $('<td>').append($this).appendTo(tr1);
        var minus = $('<div class="basket-minus">');
        $('<td>').append(minus).appendTo(tr1);
        var tr2 = $('<tr>').appendTo(tbl);
        $('<td>').appendTo(tr2);
        $('<td>').appendTo(tr2).append($('<div>').addClass('add-to-basket'));
        $('<td>').appendTo(tr2);
        $this.keypress(function (e) { if (e.which < 48 || e.which > 57) e.preventDefault(); });
        minus.click(function () {

            var a = 1; if (!isNaN($this.text())) a = parseInt($this.text()); 
            if (a > 1) a -= 1; $this.text(a);
        });
        plus.click(function () {
            var a = 1; if (!isNaN($this.text())) a = parseInt($this.text());
            if (a < 1000000) a += 1; $this.text(a);
        });
    });
}

actually I knew I could correct the code and it would work my concern was to understand why isNaN returns false but parseInt returns NaN

Ashkan Mobayen Khiabani
  • 33,575
  • 33
  • 102
  • 171
  • 3
    What exactly is the string value of `obj.text()`? Is it really just "1" or are there other characters? – Pointy Nov 17 '13 at 15:45
  • I pasted the full code – Ashkan Mobayen Khiabani Nov 17 '13 at 15:46
  • You realize that `if (false) console.log("no"); console.log("yes");` will still print out `"yes"` don't you? – nicosantangelo Nov 17 '13 at 15:47
  • 1
    (a side note: whenever you parseInt, add the radix: parseInt(str, 10), older JavaScript will surprise you otherwise) – Eric Nov 17 '13 at 15:48
  • @NicoSantangelo yes, I know, but as isNaN is false parseInt should work and after parse int a should have a value and not NaN – Ashkan Mobayen Khiabani Nov 17 '13 at 15:49
  • 1
    @AshkanMobayenKhiabani you're making an incorrect assumption about what the `isNaN()` function does. – Pointy Nov 17 '13 at 15:51
  • The problem is clearly with `obj.text()` otherwise it would work. You are probably sending isNaN an empty string. The function isNaN doesn't always do the right thing, e.g., `isNaN('') === false` Try parsing your integer **first**, then checking if it's NaN or not. Also, use `obj.val()` instead. – Joe Simmons Nov 17 '13 at 15:52
  • oh I got it when the return value is "" isNaN returns true but parseInt fails – Ashkan Mobayen Khiabani Nov 17 '13 at 15:57
  • 1
    No, isNaN will return false for `""` which makes your code think it's a number but it isn't. You should re-write your code. Use `obj.val()` – Joe Simmons Nov 17 '13 at 15:58
  • I edited my question. You asked why isNaN returns false and parseInt returns NaN, check [this link](http://stackoverflow.com/questions/8271836/isnan-vs-parseint-confusion) and [this link](http://stackoverflow.com/questions/825402/why-does-isnan-equal-false) – Joe Simmons Nov 17 '13 at 16:27
  • Let this question serve to readers that you must be **clear** in your question to get the answer you want. If you fear being misunderstood, add as much information as possible; too much is better than too little. – Joe Simmons Nov 17 '13 at 17:15

4 Answers4

5

You get the value of an <input> with .val(), not .text().

The isNaN() function returns false for isNaN(""). Why? Because when "" (the empty string) is converted to a number, it's 0. Pass a non-number to isNaN() and the first thing it does is coerce the value into a number.

It's kind-of pointless to try isNaN() before parseInt() anyway, since parseInt() will tell you when it can't parse a nice-looking integer. Note however that parseInt() doesn't care if there's garbage at the end of the input.

If you want to convert a string to a number when it's a valid string representation of a number, and NaN when it isn't, you can use

var myNumber = +myString;

That'll accept numbers with fractional parts and exponents too, so you'd have to either truncate that to just an integer or check to see if it is one:

var myNumber = +myString;
if (isNaN(myNumber))
  // not a valid number
else if (myNumber !== Math.floor(myNumber))
  // not an integer
else
  // yaay!
Pointy
  • 405,095
  • 59
  • 585
  • 614
5

The jQuery text() method will take all the descendent text nodes of an element and combine them into a single string.

An input element can't have descendant nodes of any kind. Its current value is exposed via the value property, which you can read with the val() method in jQuery.

You shouldn't use parseInt without a radix, especially with free form input. You might get octal or hex data instead of a decimal.

parseInt($this.val(), 10)
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
2
minus.click(function () {
    // let's parse the integer first
     var num = parseInt( obj.val(), 10 );

     // then later, we can check if it's NaN
     if ( !isNaN(num) && num > 1 ) {
        num -= 1;
        obj.val(num);
     }
});



actually I knew I could correct the code and it would work my concern was to understand why isNaN returns false but parseInt returns NaN

isNaN doesn't work the way it should. There is type coercion going on.
isNaN will convert the value to a number first. An empty string will be converted to a 0

Number("") === 0; // true

0 is obviously not NaN, so it returns false.

parseInt doesn't do type coercion, it parses the value differently.

Check this question and this other question for reference.

Community
  • 1
  • 1
Joe Simmons
  • 1,828
  • 2
  • 12
  • 9
0

parseInt returns NaN when the first non-whitespace character cannot be converted to a number.

  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jun 28 '22 at 06:40