user6791921
user6791921

Reputation:

Why does this JavaScript validation work depending on the order of conditions?

I am writing one small function which validates one text, and I am very upset because of the validation.

The problem is: when I try to compare the string to null (to check the cancel button), it works depending on where I put the condition! It seems to be working only when I put at the beginning of the validation. I have tested it with parenthesis for each condition too, but I get the same result.

What´s happening here?

I found this answer on Stack Overflow, but it is for Python and I don´t understand it very well:

Does the Order of Conditions affect Performance?

Code

function validate()
{
    var isValid = false;

    var text;

    while (isValid == false)
    {
        text = prompt("Enter one text between 1 and 10 characters, no empty, blank spaces, only numbers");

        /*
          WITH NULL (CANCEL BUTTON) VALIDATION AT THE BEGINNING,
          IT WORKS:
        */

        if (text != null &&
            (text.length >= 1 && text.length <= 10) &&
            text != "" &&
            isNaN(text) == false)
        {
            isValid=true;
        }

        /*
          WITH NULL (CANCEL BUTTON) VALIDATION AT ANOTHER POSITION, IT DOESN´T WORK:

          It generates "TypeError:Text is null"
        */

        if ( (text.length >= 1 && text.length < 10)  &&
             isNaN(text) == false && text != "" && text !=null)
        {
              isValid = true;
        }
    }

    if (isValid == true)
    {
        // Some code when validation is OK
    }
}

Upvotes: 1

Views: 64

Answers (3)

lealceldeiro
lealceldeiro

Reputation: 14968

In simple words:

If you evaluate text.anyproperty == null you're asking if the anyproperty of the var text is null, but this way you are taking for granted that text is not null, which will fail with the error you mentioned (TypeError) if text is actually null.

In order to avoid this pitfall you must ask first for text and then for text.anyproperty like this: if(text != null && text.anyproperty != null) ... so, this way, if text != null fails, the text.anyproperty != null will not be evaluated and you won't get the TypeError.

For the purpose of your validation, using if(text != null && text.anyproperty != null) you can achieve your goal, since if text is null, it doesn't make any sense check text.anyproperty (that's why the rest of the expression, the code after &&, is not evaluated).

Hope this help you understand better this matter :)

Upvotes: 0

Tim Roberts
Tim Roberts

Reputation: 1170

Because let's say that we had the following values:

var text = 'Tim is an alright person',
    notText = null

If we try to access a property of notText, we will get an error because null doesn't have a properties like length. So, in code:

if(text.length){...}

works because text has a length property. However, the following does not work:

if(notText.length){...}

because notText does not have a length property. It will throw the error of TypeError because you are trying to do something with the null type that is not allowed.

So, we need the text != null check first because it will fail early, before trying the other expressions.

Upvotes: 0

holtc
holtc

Reputation: 1820

You want to check if the text is not null first, because if that condition fails, the rest of the conditions will not be evaluated, since the && invariant has been violated. If the text is null, and the null check comes after some other check, you will receive an error.

Upvotes: 1

Related Questions