1

Let's take a look at this code:

var token = (req.body && req.body.access_token) ||
            (req.query && req.query.access_token) ||
            req.headers['x-access-token'];

Taken from here.

Shouldn't this return a boolean? What most confuses me is the chained AND and OR statements. I'm reading this as:

The variable token equals the boolean whether req.body AND req.body.access_token exist. OR, if they don't exist, then it equals the boolean whether req.query AND req.query.access_token exist. OR, if they don't exist, it equals the value of req.headers['x-access-token'].

Furthermore, if we analyze just this piece:

var token = req.body && req.body.access_token;

What keeps the token from being set to req.body?

Kenny Worden
  • 4,335
  • 11
  • 35
  • 62

1 Answers1

2

It's not really evaluating a boolean expression and assigning that to token. What you have there is a kind of shorthand if-else. Let's break it down:

(req.body && req.body.access_token)

If req.body is "truthy" (in this particular case it is ensuring that it is not null or undefined, probably) then it will assign req.body.access_token to token. The expression will short-circuit here and will not proceed.

Otherwise, it looks at the next case:

(req.query && req.query.access_token)

This is the same as the above; except in this case it assigns req.query.access_token to token if req.query is "truthy". It will also short-circuit here unless "falsy".

req.headers['x-access-token'];

This is the final clause. If none of the preceding cases are true, it will assign the value of req.headers['x-access-token'] to token.

In the traditional form, it would look like this:

var token;
if(req.body && req.body.access_token) {
    token = req.body.access_token;
} else if(req.query && req.query.access_token) {
    token = req.query.access_token;
} else {
    token = req.headers['x-access-token'];
}

What keeps the token from being set to req.body?

The expression is:

var token = req.body && req.body.access_token;

It won't set token to req.body. Here, req.body is kind of acting as a flag. We don't want to do req.body.access_token directly because req.body could be null or undefined. So what it's doing here is saying "if req.body is non-null/defined, then assign req.body.access_token to token". Realize that if the first term of an && is true, the second term must still be evaluated because the only time an AND is true is when both operands are true. However the advantage here is that "evaluating" the second term returns the value of that term as well, which is what set as token eventually.

More explicitly, the above expression can be represented as:

if(req.body !== null || typeof req.body !== "undefined") {
    token = req.body.access_token;
}

But in JavaScript you can simply check if(some_var) and that won't run the code in the if block if some_var is undefined or null. But you have to be careful because legitimate values like 0 or an empty-string are "falsy", and you could end up ignoring them.

Vivin Paliath
  • 94,126
  • 40
  • 223
  • 295
  • More info on [**Short-circuit evaluation**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Short-Circuit_Evaluation). Perfect answer, +1. – blex Jul 16 '15 at 23:36
  • I'm assuming you can only get this behaviour with logical OR (`||`) statements? I.e. you can't short-circuit an expression with AND statements? – Kenny Worden Jul 16 '15 at 23:38
  • @KennyWorden I made this [**demo**](http://jsfiddle.net/bbpa118L/) to demonstrate what happens with `&&`. – blex Jul 16 '15 at 23:39
  • Take some time to read the link I posted in my first comment. They give examples to show how it works. – blex Jul 16 '15 at 23:42
  • @KennyWorden you can use it with `&&`; the value of the final term will be returned if all preceding terms evaluate to `true`. Otherwise the result will be `false`. – Vivin Paliath Jul 16 '15 at 23:44
  • @VivinPaliath http://stackoverflow.com/a/31444174/1503130 please update your answer for the query ... I am really stuck here.. an urgent requirement has come to me.. – Prateek Jul 20 '15 at 11:46