19

Is there a better way to improve the below statement to check if the val() is 'true' or 'false' and if it is then it will change it to a Boolean. The reason being, some of the values may be a word.

var thisval = $(this).val();
if (thisval == "true"){
    ao[id] = true;
} else if (thisval == "false"){
    ao[id] = false;
} else {
    ao[id] = $(this).val();
}
2
  • 2
    possible duplicate of How can I convert a string to boolean in JavaScript? Commented Nov 11, 2013 at 13:31
  • Whats wrong with this code? All answers so far, in my opinion, are less readable. Extract into a function (accepting a string, returning a boolean or string) and never worry about it again. Commented Jan 8, 2019 at 9:58

10 Answers 10

26

Most readable:

var thisval = $(this).val();
ao[id] = thisval === 'true' ? true : 
         thisval === 'false' ? false : 
         thisval;

One-liner based on the conditional operator:

var thisval = $(this).val();
ao[id] = thisval === 'true' ? true : (thisval === 'false' ? false : thisval);

One-liner based on || and && behavior:

var thisval = $(this).val();
ao[id] = thisval === 'true' || (thisval !== 'false') && thisval || false;

Shortest one-liner (combination of the above):

var thisval = $(this).val();
ao[id] = thisval === 'true' || (thisval === 'false' ? false : thisval);
Sign up to request clarification or add additional context in comments.

5 Comments

Third solution is the best to me because, even in a case where we don't know for sure that thisval is a string , at the end, if not equal to true or false, we can assume thisval is probably already a Boolean and if it's not it wont pass further test anyway.
@svassr All 3 solutions behave the same (give exactly the same output for any input). The only difference is in what JS operators are used. I believe that with the proper optimizations they might even result in the same bytecode.
Right indeed. I understood that, I was just confused because I was reading 3 posts on the topic at the same time :p
@Gaspa79 The code is equivalent to that of the OP - values other than 'true' and 'false' are returned as they are. The conditional operator does not enforce anything about the type of the result. Run the code in the console to convince yourself :D.
@Tibos I stand corrected. The ? operator doesn't work the same way it does in strongly typed languages it seems. I did well in giving you +1 before. Thanks.
13

Try JSON.parse().

"true" and "false" are actually json representations of true, false. This is how ajax parses json object as a string from server side. If on server side, we return true, false => the browser will receive it as a string "true" or "false" (json representation)

if ( $(this).val() == "true" ||  $(this).val() == "false") {
    ao[id] = JSON.parse($(this).val());
}else {
    ao[id] = $(this).val();
}

DEMO

4 Comments

Using JSON just for parsing something you know can only be either "true" or "false"sounds like quite an overkill... also, the .val() method wil be called three times every time the code above is called.
@Haroldo_OK: I don't think it's overkill, that's also something we use when we parse response from server.
this also works for numbers, eg. JSON.parse('123') // returns 123
Great answer!! Very innovate answer to a very common problem.
3
String.prototype.bool = function() {
    return (/^true$/i).test(this);
};


if ( $(this).val() == "true" ||  $(this).val() == "false") {
    ao[id] = $(this).val().bool();
}else {
    ao[id] = $(this).val();
}

Comments

1

This might be slightly more elegant:

var thisval = $(this).val();

if (thisval === "true" || thisval === "false") {
    thisval = (thisval === "true");
}

Comments

1
('' + thisval).toLowerCase() === 'true'

May be useful if extra string and toLower is negligible - may be simple.

Its true if its explicitly set to true, (boolean or case insensitive string) and false otherwise.

 // so complete solution to get the same value if neither true nor false
const thisvalStr = ('' + thisval).toLowerCase();
a[id] = thisvalStr === 'true'? true: (thisvalStr === 'false')? false: thisval;

Can be modified to include additional values like, 1, etc as per need by using || or an array.

const TrueValuesStr = ['1', 'true']

TrueValueStr.contains(('' + thisval).toLowerCase() === 'true')

Comments

1

In the pleasant summer of 2022, here's how I'd do it:

const thisval = $(this).val();

ao[id] = ['true', 'false'].includes(thisval) ? JSON.parse(thisval) : thisval;

You could also go a step further and have it handle numbers too:

ao[id] = ['true', 'false'].includes(thisval) || !Number.isNaN(Number(thisval))
  ? JSON.parse(thisval)
  : thisval;

Comments

0
var thisval = $(this).val();

switch(thisval) { 
case 'true' : 
    ao[id] = true; 
    break; 

case 'false' : 
    ao[id] = false; 
    break; 

default: 
    ao[id] = thisval; 

}

I would create an array to hold the two possible values for when the string is true or false. Then, I would search to see if thisval is found inside that array. If it is not, the indexOf function will return -1. Afterwards, it is just a matter of going over those values and build up the cases that you want.

EDIT: I have updated the code based on the suggestion of Tibos. Thank you!

5 Comments

The OP did ask for a way to improve his code, where is the improvement?
Usually, when there are more than 2 if statements, switch shows better performance. That is the only thing I kept in mind when providing my answer. I thought that by 'improved way' the asker meant performance management :)
The improvement in performance for this would be minimal and not noticeable. Caching his $(this).val() would be useful in any case, but this code just seems more longwinded in my opinion.
Indexof negates all the performance benefit from going to a switch instead of two ifs. Why not switch(thisval) { case 'true' : ao[id] = true; break; case 'false' : ao[id] = false; break; default: ao[id] = thisval; }?
You are right, Tibos! That would be faster indeed! I will update the code accordingly.
0

I'd prob prefer

const parseMaybeBool = val =>
  typeof val === 'string'
    ? val.toLowerCase() === 'true' || val.toLowerCase() === 'false'
      ? Boolean(val)
      : val
    : val;

or w/ types

const isBool = (val: unknown): val is boolean =>
  typeof val === 'boolean' ||
  (typeof val === 'string' &&
    (val.toLowerCase() === 'true' || val.toLowerCase() === 'false'));

const parseMaybeBool = (val: unknown) =>
  isBool(val) ? Boolean(val) : val;

Comments

0

You can do all of this in one line if you want to:

const getBool = value => value == "true" || value == "false" ? value == "true" : value;

getBool($(this).val());

Explanation

In JavaScript you'll probably be used to using something like

if(answer == "yes"){ ...

answer == "yes" will evaluate to true or false.

For your question, this can certainly help one part of it. If there were only "true" or "false" options it would be as simple as:

const getBool = (value) => value == "true"
getBool("true"); // true
getBool("false"); // false

We can now wrap this in a ternary operator, basic overview:

`if this` ? `then do this` : `if not, then do this`

So we check if the value is true or false, and if so use the above technique.

value == "true" || value == "false" 

If its not, we can just return the value without any modifications. So the test becomes:

value == "true" || value == "false" ? value == "true" : value;

Comments

-1

In nodejs by using node-boolify we can use isBoolean() & Boolify()

Validation Results

var isBoolean = require('node-boolify').isBoolean;

isBoolean(true); //true
isBoolean('true'); //true
isBoolean('TRUE'); //false
isBoolean(1); //true
isBoolean(2); //false
isBoolean(false); //true
isBoolean('false'); //true
isBoolean('FALSE'); //false
isBoolean(0); //true
isBoolean(null); //false
isBoolean(undefined); //false
isBoolean(); //false
isBoolean(''); //false

Boolean Conversion Results

var Boolify = require('node-boolify').Boolify;

Boolify(true); //true
Boolify('true'); //true
Boolify('TRUE'); //null
Boolify(1); //true
Boolify(2); //null
Boolify(false); //false
Boolify('false'); //false
Boolify('FALSE'); //null
Boolify(0); //false
Boolify(null); //null
Boolify(undefined); //null
Boolify(); //null
Boolify(''); //null

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.