fatCop
fatCop

Reputation: 2576

Null checking in Javascript (with ternary operator)

want to check null values. any() method returns null or array of matched result (actually there's a match() method inside which is returned).

$scope.isMobileBrowser = !isMobile.any() ? false : true;

If any() method returns null I want false to be assigned to $scope.isMobileBrowser variable, otherwise true. will the over mentioned snippet fail in any probable case? Is there any other more efficient workaround?

for more details of isMobile object:

var isMobile = {
    Android: function() {
        return navigator.userAgent.match(/Android/i);
    },
    BlackBerry: function() {
        return navigator.userAgent.match(/BlackBerry/i);
    },
    iOS: function() {
        return navigator.userAgent.match(/iPhone|iPad|iPod/i);
    },
    Opera: function() {
        return navigator.userAgent.match(/Opera Mini/i);
    },
    Windows: function() {
        return navigator.userAgent.match(/IEMobile/i);
    },
    any: function() {
        return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
    }
};

Upvotes: 0

Views: 17781

Answers (4)

rossipedia
rossipedia

Reputation: 59367

A compact way of representing what you want would be:

$scope.isMobileBrowser = !!isMobile.any();

The !! there does two things:

  1. The first ! evaluates the "truthiness"1 of the return value of isMobile.any() and then negates it.
  2. The second ! negates that value again.

So what you end up with is false if .any() returns null, otherwise true.

However, this may fail in edge cases where .any() returns something that is "falsy". In that case, checking for null specifically is what you want:

isMobile.any() !== null

1: "Truthiness":

In JavaScript, a truthy value is a value that translates to true when evaluated in a Boolean context. All values are truthy unless they are defined as falsy (i.e., except for false, 0, "", null, undefined, and NaN).

From MDN

Upvotes: 0

sabithpocker
sabithpocker

Reputation: 15568

As per the any() function, you are returning value of the following expression:

(isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() 
                             || isMobile.Opera() || isMobile.Windows())

Each of these functions can either return an Array or null as seen in the doc for match

So while evaluating the OR it will evaluate to the first truth value encountered and doesnt evaluate any further as the expression is already fit to be true. So, for example if the browser is android the expression evaluates to ["Android"]. If windows it will be ["Windows"]. If none of these, it will be null. Which makes it clear that any() can only return an Array or null.

isMobileBrowser should be true if it's any of these mobile browsers, which means isMobileBrowser should be true if:

any() evaluates to an Array

OR in other way:

If any() does not evaluate to null

which is:

$scope.isMobileBrowser = isMobile.any() instanceof Array;//looks messy
$scope.isMobileBrowser = (isMobile.any()).constructor === Array;//looks messy
$scope.isMobileBrowser = Array.isArray(isMobile.any());//looks messy
$scope.isMobileBrowser = Object.prototype.toString.call(isMobile.any()) 
                                   === "[object Array]";//looks messy

OR the other way:

$scope.isMobileBrowser = isMobile.any() !== null;
$scope.isMobileBrowser = !(isMobile.any() === null);
isMobileBrowser = !(Object.prototype.toString.call(isMobile.any()) 
                                   === "[object Null]");//looks messy

So we just discussed different ways to check for null and Array. You have two possible sets of outputs

  1. null value which is always false
  2. An Array which is always true (You can check this empty array scenario although that doesn't apply here)

So you can simply do the following to convert those to exact boolean without worrying much:

isMobileBrowser = Boolean(isMobile.any()); //to convert value to boolean
isMobileBrowser = !!isMobile.any(); //another way to convert to boolean
                                   //!!["Android"] is true
                                   //!!null is false

@rossipedia explains the !! well in his answer.

Upvotes: 1

lexicore
lexicore

Reputation: 43651

Empty string is also a falsy value.
If any() returns an empty string, !isMobile.any() ? false : true will return false, but you probably want true.

This means your code is incorrect for this case.

I'd just do something like isMobile.any() !== null.

Upvotes: 5

Bardo
Bardo

Reputation: 2523

Try this:

$scope.isMobileBrowser = isMobile.any() === null;

Upvotes: -1

Related Questions