93

JavaScript has parseInt() and parseFloat(), but there's no parseBool or parseBoolean method in the global scope, as far as I'm aware.

I need a method that takes strings with values like "true" or "false" and returns a JavaScript Boolean.

Here's my implementation:

function parseBool(value) {
    return (typeof value === "undefined") ? 
           false : 
           // trim using jQuery.trim()'s source 
           value.replace(/^\s+|\s+$/g, "").toLowerCase() === "true";
}

Is this a good function? Please give me your feedback.

Thanks!

Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
  • and you can also post your code on http://codereview.stackexchange.com if you're only looking for code reviews... – peirix Mar 07 '11 at 11:36
  • see http://stackoverflow.com/questions/263965/how-can-i-convert-a-string-to-boolean-in-javascript – Alex Pacurar Mar 07 '11 at 11:50

14 Answers14

103

I would be inclined to do a one liner with a ternary if.

var bool_value = value == "true" ? true : false

Edit: Even quicker would be to simply avoid using the a logical statement and instead just use the expression itself:

var bool_value = value == 'true';

This works because value == 'true' is evaluated based on whether the value variable is a string of 'true'. If it is, that whole expression becomes true and if not, it becomes false, then that result gets assigned to bool_value after evaluation.

Soviut
  • 88,194
  • 49
  • 192
  • 260
raddrick
  • 4,274
  • 2
  • 27
  • 33
  • 45
    Why not shorten it a bit further? `var bool_value = value == "true"` does the same thing :) – Jakob Apr 08 '12 at 10:59
  • 12
    A ternary expression could be useful here, to handle the case where you're passed null/undefined/empty: `bool_value = value ? (value.toLowerCase() == "true") : false` – parsifal Oct 10 '12 at 20:45
  • 1
    `"true" ? true : false` is ternary, but yes it can be expanded to check for `null/undefined/empty` – raddrick Oct 12 '12 at 20:09
  • 2
    I use the following ternary: !value || value === 'false' ? false : true; It will trap the following properly: false, true, "false", "true", 0, 1, "", and undefined – Matt James Feb 27 '14 at 15:27
  • the reason i wouldn't use a ternary operator of the shorter one is for clarity :) – thermite Nov 19 '14 at 04:34
  • 6
    Shorter way: `var bool = !!value` – Ifch0o1 Dec 14 '14 at 16:42
  • agree with @Ifch0o1 about !!valuee being better. and you can verify that it works like this: !!value === true this will however extend this check to include other truthy values such as 1 which may or may not be welcome – Sonic Soul Jun 14 '16 at 17:57
  • 2
    @Ifch0o1 I wouldn't use `var bool = !!value`. The string containing "false" is a truthy value so `!!'false' === true` – Michael Lang Sep 26 '18 at 21:13
  • @Michael Lang the ! Operator parses the next value to boolean true or false. It didnt return a string, it return boleab. When used twice, returns revert bolean and again revert bolean which is the bolean value of the variable. – Ifch0o1 Oct 01 '18 at 09:32
  • 3
    I typically expect that when someone says they want to "parse a string into a boolean" they mean that they want to map the string "false" to the boolean value false. However in javascript, !!'false' yields the boolean value true. If you don't believe me, open the javascript console in your favorite browser or a nodeJS repl and try it yourself. If the original poster is ok with this "parsing" taking "false" to true then I suppose !! is just fine, but that's certainly not the behavior I'd expect from a parser. – Michael Lang Oct 23 '18 at 21:24
98

You can use JSON.parse for that:

JSON.parse("true"); //returns boolean true
F.Alves
  • 1,281
  • 9
  • 9
17

It depends how you wish the function to work.

If all you wish to do is test for the word 'true' inside the string, and define any string (or nonstring) that doesn't have it as false, the easiest way is probably this:

function parseBoolean(str) {
  return /true/i.test(str);
}

If you wish to assure that the entire string is the word true you could do this:

function parseBoolean(str) {
  return /^true$/i.test(str);
}
Paul Fleming
  • 24,238
  • 8
  • 76
  • 113
Martin Jespersen
  • 25,743
  • 8
  • 56
  • 68
  • 2
    The way this natively works is absolutely stupid. The Boolean function should do the latter of your examples. If one needs to see if a string contains the word true or false then you should check if the index is > 0. – The Muffin Man May 21 '12 at 22:25
  • This has a huge amount of overhead matching with regex, instead of simply checking if the string contains 'true' or not. – Soviut Aug 05 '13 at 08:15
  • @Soviut: quite right, RGBs solution is much prfered – Martin Jespersen Aug 06 '13 at 11:30
11

You can try the following:

function parseBool(val)
{
    if ((typeof val === 'string' && (val.toLowerCase() === 'true' || val.toLowerCase() === 'yes')) || val === 1)
        return true;
    else if ((typeof val === 'string' && (val.toLowerCase() === 'false' || val.toLowerCase() === 'no')) || val === 0)
        return false;

    return null;
}

If it's a valid value, it returns the equivalent bool value otherwise it returns null.

Paul Fleming
  • 24,238
  • 8
  • 76
  • 113
  • This almost worked, I tweaked it a bit to get it to work properly (single quotes around `'string'`): `function parseBool(val) { if ((typeof val == 'string' && (val.toLowerCase() === 'true' || val.toLowerCase() === 'yes')) || val === 1) return true; else if ((typeof val === 'string' && (val.toLowerCase() === 'false' || val.toLowerCase() === 'no')) || val === 0) return false; return null; }` – delliottg Jul 11 '14 at 15:27
  • @delliottg Updated with quotes on *string*. – Paul Fleming Jul 14 '14 at 08:04
4

last but not least, a simple and efficient way to do it with a default value :

ES5

function parseBool(value, defaultValue) {
    return (value == 'true' || value == 'false' || value === true || value === false) && JSON.parse(value) || defaultValue;
}

ES6 , a shorter one liner

const parseBool = (value, defaultValue) => ['true', 'false', true, false].includes(value) && JSON.parse(value) || defaultValue

JSON.parse is efficient to parse booleans

Sebastien H.
  • 6,818
  • 2
  • 28
  • 36
4

You can use JSON.parse or jQuery.parseJSON and see if it returns true using something like this:

function test (input) {
    try {
        return !!$.parseJSON(input.toLowerCase());
    } catch (e) { }
}
Paul Fleming
  • 24,238
  • 8
  • 76
  • 113
rsp
  • 107,747
  • 29
  • 201
  • 177
  • Looks a bit dangerous to me. For example, `test("\"false\"")` will return `true` for being a non-empty string. It's unlikely, but a very unobvious source for bugs. – RoToRa Mar 07 '11 at 11:59
  • If the input is invalid JSON, this function will return `undefined`. – PleaseStand Mar 07 '11 at 12:11
  • @idealmaschine: Which seems to be a Good Thing to me. Is that what you wanted to say, or was that a criticism? – RoToRa Mar 07 '11 at 12:16
  • @RoToRa: Good point. But not knowing the data it's hard to know if "\"false\"" should be true or false – and what about "\"not true\"" or "\"no\"" or "yes"? One possibility would be to return undefined for everything other than explicit true or false, or use the usual JavaScript or JSON semantics, or use some custom logic that is suitable for a given application. It's hard to make a universal solution if it is even hard to find two programming languages that would agree on what is true and what is false. – rsp Mar 07 '11 at 13:15
  • @idealmaschine: You can add `return false;` in the catch block if you want to get false for invalid JSON, but keep in mind that undefined is also falsy in JavaScript so it may not really matter, depending on how you use it. – rsp Mar 07 '11 at 13:18
3

Why not keep it simple?

var parseBool = function(str) {
    if (typeof str === 'string' && str.toLowerCase() == 'true')
            return true;

    return (parseInt(str) > 0);
}
MiniGod
  • 3,683
  • 1
  • 26
  • 27
3

You can add this code:

function parseBool(str) {
  
  if (str.length == null) {
    return str == 1;
  } else {
    return str == "true";
  }
 
}

Works like this:

parseBool(1) //true
parseBool(0) //false
parseBool("true") //true
parseBool("false") //false
CodeGems
  • 549
  • 4
  • 16
  • 2
    I see ternarys used a lot like this but they aren't needed. You can just do `return (str === 1)` – Hexodus Jun 25 '21 at 13:11
3

Personally I think it's not good, that your function "hides" invalid values as false and - depending on your use cases - doesn't return true for "1".

Another problem could be that it barfs on anything that's not a string.

I would use something like this:

function parseBool(value) {
  if (typeof value === "string") {
     value = value.replace(/^\s+|\s+$/g, "").toLowerCase();
     if (value === "true" || value === "false")
       return value === "true";
  }
  return; // returns undefined
}

And depending on the use cases extend it to distinguish between "0" and "1".

(Maybe there is a way to compare only once against "true", but I couldn't think of something right now.)

RoToRa
  • 37,635
  • 12
  • 69
  • 105
  • Sorry to dredge up really old code, but why not just `return true;`? why `return value === "true";`? I mean, you already checked if it's valid, right? – Metagrapher Mar 19 '15 at 01:25
  • @Metagrapher If I just `return true`, it will return true, if the value is `"false"`, too. – RoToRa Mar 19 '15 at 09:37
  • I don't know what was wrong with me when I read that code. Sorry. haha thanks for the clarity. – Metagrapher Mar 21 '15 at 22:19
2

Wood-eye be careful. After looking at all this code, I feel obligated to post:

Let's start with the shortest, but very strict way:

var str = "true";
var mybool = JSON.parse(str);

And end with a proper, more tolerant way:

var parseBool = function(str) 
{
    // console.log(typeof str);
    // strict: JSON.parse(str)

    if(str == null)
        return false;

    if (typeof str === 'boolean')
    {
        if(str === true)
            return true;

        return false;
    } 

    if(typeof str === 'string')
    {
        if(str == "")
            return false;

        str = str.replace(/^\s+|\s+$/g, '');
        if(str.toLowerCase() == 'true' || str.toLowerCase() == 'yes')
            return true;

        str = str.replace(/,/g, '.');
        str = str.replace(/^\s*\-\s*/g, '-');
    }

    // var isNum = string.match(/^[0-9]+$/) != null;
    // var isNum = /^\d+$/.test(str);
    if(!isNaN(str))
        return (parseFloat(str) != 0);

    return false;
}

Testing:

var array_1 = new Array(true, 1, "1",-1, "-1", " - 1", "true", "TrUe", "  true  ", "  TrUe", 1/0, "1.5", "1,5", 1.5, 5, -3, -0.1, 0.1, " - 0.1", Infinity, "Infinity", -Infinity, "-Infinity"," - Infinity", " yEs");

var array_2 = new Array(null, "", false, "false", "   false   ", " f alse", "FaLsE", 0, "00", "1/0", 0.0, "0.0", "0,0", "100a", "1 00", " 0 ", 0.0, "0.0", -0.0, "-0.0", " -1a ", "abc");


for(var i =0; i < array_1.length;++i){ console.log("array_1["+i+"] ("+array_1[i]+"): " + parseBool(array_1[i]));}

for(var i =0; i < array_2.length;++i){ console.log("array_2["+i+"] ("+array_2[i]+"): " + parseBool(array_2[i]));}

for(var i =0; i < array_1.length;++i){ console.log(parseBool(array_1[i]));}
for(var i =0; i < array_2.length;++i){ console.log(parseBool(array_2[i]));}
Stefan Steiger
  • 78,642
  • 66
  • 377
  • 442
0

I like the solution provided by RoToRa (try to parse given value, if it has any boolean meaning, otherwise - don't). Nevertheless I'd like to provide small modification, to have it working more or less like Boolean.TryParse in C#, which supports out params. In JavaScript it can be implemented in the following manner:

var BoolHelpers = {
    tryParse: function (value) {
        if (typeof value == 'boolean' || value instanceof Boolean)
            return value;
        if (typeof value == 'string' || value instanceof String) {
            value = value.trim().toLowerCase();
            if (value === 'true' || value === 'false')
                return value === 'true';
        }
        return { error: true, msg: 'Parsing error. Given value has no boolean meaning.' }
    }
}

The usage:

var result = BoolHelpers.tryParse("false");
if (result.error) alert(result.msg);
jwaliszko
  • 16,942
  • 22
  • 92
  • 158
0

stringjs has a toBoolean() method:

http://stringjs.com/#methods/toboolean-tobool

S('true').toBoolean() //true
S('false').toBoolean() //false
S('hello').toBoolean() //false
S(true).toBoolean() //true
S('on').toBoolean() //true
S('yes').toBoolean() //true
S('TRUE').toBoolean() //true
S('TrUe').toBoolean() //true
S('YES').toBoolean() //true
S('ON').toBoolean() //true
S('').toBoolean() //false
S(undefined).toBoolean() //false
S('undefined').toBoolean() //false
S(null).toBoolean() //false
S(false).toBoolean() //false
S({}).toBoolean() //false
S(1).toBoolean() //true
S(-1).toBoolean() //false
S(0).toBoolean() //false
prule
  • 2,536
  • 31
  • 32
0

I shamelessly converted Apache Common's toBoolean to JavaScript:

JSFiddle: https://jsfiddle.net/m2efvxLm/1/

Code:

function toBoolean(str) {
  if (str == "true") {
    return true;
  }
  if (!str) {
    return false;
  }
  switch (str.length) {
    case 1: {
      var ch0 = str.charAt(0);
      if (ch0 == 'y' || ch0 == 'Y' ||
          ch0 == 't' || ch0 == 'T' ||
          ch0 == '1') {
        return true;
      }
      if (ch0 == 'n' || ch0 == 'N' ||
          ch0 == 'f' || ch0 == 'F' ||
          ch0 == '0') {
        return false;
      }
      break;
    }
    case 2: {
      var ch0 = str.charAt(0);
      var ch1 = str.charAt(1);
      if ((ch0 == 'o' || ch0 == 'O') &&
          (ch1 == 'n' || ch1 == 'N') ) {
        return true;
      }
      if ((ch0 == 'n' || ch0 == 'N') &&
          (ch1 == 'o' || ch1 == 'O') ) {
        return false;
      }
      break;
    }
    case 3: {
      var ch0 = str.charAt(0);
      var ch1 = str.charAt(1);
      var ch2 = str.charAt(2);
      if ((ch0 == 'y' || ch0 == 'Y') &&
          (ch1 == 'e' || ch1 == 'E') &&
          (ch2 == 's' || ch2 == 'S') ) {
        return true;
      }
      if ((ch0 == 'o' || ch0 == 'O') &&
          (ch1 == 'f' || ch1 == 'F') &&
          (ch2 == 'f' || ch2 == 'F') ) {
        return false;
      }
      break;
    }
    case 4: {
      var ch0 = str.charAt(0);
      var ch1 = str.charAt(1);
      var ch2 = str.charAt(2);
      var ch3 = str.charAt(3);
      if ((ch0 == 't' || ch0 == 'T') &&
          (ch1 == 'r' || ch1 == 'R') &&
          (ch2 == 'u' || ch2 == 'U') &&
          (ch3 == 'e' || ch3 == 'E') ) {
        return true;
      }
      break;
    }
    case 5: {
      var ch0 = str.charAt(0);
      var ch1 = str.charAt(1);
      var ch2 = str.charAt(2);
      var ch3 = str.charAt(3);
      var ch4 = str.charAt(4);
      if ((ch0 == 'f' || ch0 == 'F') &&
          (ch1 == 'a' || ch1 == 'A') &&
          (ch2 == 'l' || ch2 == 'L') &&
          (ch3 == 's' || ch3 == 'S') &&
          (ch4 == 'e' || ch4 == 'E') ) {
        return false;
      }
      break;
    }
    default:
      break;
  }

  return false;
}
console.log(toBoolean("yEs")); // true
console.log(toBoolean("yES")); // true
console.log(toBoolean("no")); // false
console.log(toBoolean("NO")); // false
console.log(toBoolean("on")); // true
console.log(toBoolean("oFf")); // false
Inspect this element, and view the console output.
Xaero Degreaz
  • 1,045
  • 11
  • 18
-6

Enough to using eval javascript function to convert string to boolean

eval('true')  
eval('false')
Jens Erat
  • 37,523
  • 16
  • 80
  • 96
MKD
  • 1
  • 3
    Eval breaks lots of optimizations, results in slow code, is hard to debug and bad to maintain. If you can, never use it - there are much better ways to solve this problem, see the other answers. – Jens Erat May 02 '13 at 22:03
  • 1
    In this case, none of your listed is not critical and applicable. – MKD Jun 11 '13 at 07:16
  • 2
    Jens everything you mention doesn't apply in this case, but the actually important problem with this is not mentioned, security. eval can lead to js injection, so don't use it if you can't trust the input source, and if you're on a browser you can hardly trust in that ever. JSON.parse is the safe way (not sure if the fastest). – Benja Sep 11 '13 at 23:39