37

How could the following code sometimes evaluate to false?

(transport.responseText == '1' || 
 transport.responseText == 'CARD_VALID')

My JavaScript code:

if (transport.responseText == '1' || 
    transport.responseText == 'CARD_VALID') {
    // do something.
}
else if (transport.responseText == 'CARD_INVALID' || 
             transport.responseText == 'INVALID_CHECKSUM') {
    // do something else....
}
else {
    new Ajax.Request('/report_error.php?responseText='+transport.responseText);
    // report error to user
}

What could cause JavaScript string compare == to return false when the strings are identical?

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
chaimp
  • 16,897
  • 16
  • 53
  • 86
  • 1
    The JavaScript equality operator `==` is not buggy, it does not fail. It will return true if the string to the left and right have the same content. If it is returning false then either: 1. the strings are not the same. 2.there is whitespace before and after one string, or 3. there are hidden control characters or unicode characters in one string. – Eric Leschinski Oct 29 '13 at 03:07
  • I solved by adding `.trim()` but could also use `.toString()` when comparing other values – nodws Mar 06 '19 at 17:29

10 Answers10

67

Double equals is the appropriate way to compare strings in Javascript, it is returning false then there may be whitespace to the left and or right of one string.

Put a .trim() on the end of the strings and my comparison should started working:

var panel = response.substr(0, response.indexOf("<")).trim();
if(panel == "combo"){
    //do something
}
Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
Jacob
  • 694
  • 6
  • 3
  • 2
    Wow, this is such an old question, but thank you for answering. I probably tried that, but who knows... that was over three years ago. To anyone else having this issue: Please try this. If it works, comment here and I'll mark this answer as correct! – chaimp Sep 27 '12 at 01:21
  • 1
    Yep. This is a good tip. I was comparing «identical» (even with regard to visible whitespaces) strings as well, but they were not matching because one of them had a newline or a carriage return (or something) which did not print when I was trying to figure out what was wrong. – Ярослав Рахматуллин Sep 28 '12 at 16:09
  • 4
    Should really use equivalence comparison: if (panel === "combo"). – retrodrone Oct 18 '12 at 13:36
  • I have the opposite problem, where 2 extremely different strings are returning equal, it is blowing my mind. – Joe Yahchouchi May 19 '17 at 10:43
  • 2
    You saved my sanity - a quick check with .length proved my two strings which looked the same really were not equivalent after all! – BluDragn Jan 17 '18 at 21:46
  • ok today I hate javascript. I think this behavior changed in a certain version of javascript. All my code that used to just work now needs `trim()` everywhere. – toddmo Mar 01 '20 at 16:35
17
A1 = "speed"
A2 = "speed" 

if(A1 == A2)  => Error !!!

USE THIS TEST IN CONSOLE:

escape("speed")

result: "speed"

escape(A1)

result: "speed%0D" => This is the problem %0D !!!

escape(A2)

result: "speed" => OK !!!

Use correct code:

if(A1.slice(0, -1) == A2) This is OK!
M--
  • 25,431
  • 8
  • 61
  • 93
Lightlion
  • 171
  • 1
  • 2
  • 2
    Welcome to SO. Format your answer and try to provide some comments. Provide an actual answer instead of a pseudo-code when possible (including now). Your answer should add something to precious answers provided by other users. A new approach or point otherwise it is redundant. – M-- Apr 17 '17 at 16:10
  • 2
    They say that one picture is equal to 1000 words! The same can be said about the source code! People write what they think, but sometimes it's hard to understand the idea and how to check it out. Personally, it has always been easier for me to see three lines of code than to understand what people think when they explain in a lot of words. Of course, once the benefit is not visible, I will not write and comment more. Greetings! – Lightlion May 11 '17 at 09:08
  • Watchout! Now `escape` was deprecated and replaced by `encodeURI` https://www.w3schools.com/jsref/jsref_encodeuri.asp – vintagexav Dec 06 '19 at 19:21
16

I had a similar problem where two obviously identical strings would not be equal, and I was pulling my hair out trying to solve it, so I did this:

for (var c=0; c<string_1.length; c++) {
    if (string_1.charCodeAt(c) != string_2.charCodeAt(c)) {
        alert('c:'+c+' '+string_1.charCodeAt(c)+'!='+string_2.charCodeAt(c));
        valid = false;
    }
}

And I found that the last character on one string was 10, and the last character on the other was 13, I thought both strings were null terminated, but they were not.

Robert
  • 14,999
  • 4
  • 39
  • 46
6

I had the same problem and i noticed that i was comparing two objects

enter image description here

to solve this issue i had to use

JSON.stringify(user._id) === JSON.stringify(userId) // true 
Ahmed Younes
  • 964
  • 12
  • 17
5

Try using === to match exactly (type and value). This is the recommended comparison operator in javascript.

Check the datatypes of the strings to make sure, and look for hidden unicode or control characters in both strings.

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
sat
  • 40,138
  • 28
  • 93
  • 102
5

I would advice you to use normalization preferably "NFKC" or "NFKD" as these seem to normalize non-breaking space into regular space.

So you can write your code as :-

string1.normalize("NFKC") === string2.normalize("NFKC")
Yatharth Varshney
  • 1,973
  • 20
  • 22
3

If you want something a little less complicated and you are dealing with NUMERIC VALUES, use

parseFloat()

works like a charm

Jamisco
  • 1,658
  • 3
  • 13
  • 17
2

Try capturing the value of responseText into a different variable before entering that code block, in case the variable is updated somewhere in there.

I don't have that much experience directly using XmlHttpRequest, but I do know that javascript has a number of places where it uses volatile references to interface objects that can change during execution, rather than a simple value.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • Good idea but is that possible? I thought JS was mono-threaded. – PhiLho May 14 '09 at 14:35
  • Thank you for the answer. That made sense to me, so I tried it. However, we are still getting in the error log "CARD_VALID" implying that JS evaluated ('CARD_VALID' == 'CARD_VALID') to false. Any other thoughts? This is one or two per day out of hundreds of successful. The only "pattern" is that the for most of them the user-agent appears to be IE7 or IE7, however there was one that was IE6... – chaimp May 18 '09 at 14:08
0

Java servlet may send strings i.e.

out.println("CARD_VALID");

or

out.print("CARD_VALID");

These may look identical in Javascript, but there are white spaces at the end in the first case.

Kaj Risberg
  • 617
  • 9
  • 15
0

casting worked for me

if (timeSlots[j].id + '' == product.timeSlots[k].id + '') {
}
S.B
  • 13,077
  • 10
  • 22
  • 49
Rafiq
  • 8,987
  • 4
  • 35
  • 35