TheRealMrCrowley
TheRealMrCrowley

Reputation: 976

using logical OR operator (a || b) to run one of two function in JS

why is it that I can only call one of two functions using a ternary operator?

what I'd like to do:

newToken(account, request, response, returning = false) {
  /* Irrelevant code ommitted */
    return Promise.resolve((returning || response.json)({message: 'ok', account}))
}

the above uses the logical OR operator to select the returning function if available otherwise just set a json response

however, when I set the code up this way i get an error: Cannot read 'app' of undefined

if I use a ternary instead, the code works fine:

newToken(account, request, response, returning = false) {
  /* Irrelevant code ommitted */
    return Promise.resolve(returning ? returning({message: 'ok', account}) : response.json({message: 'ok', account}))
}

if I just run console.log((returning || response.json)) the correct function is always logged, so why can't I run the functions when set like this?

Upvotes: 0

Views: 629

Answers (1)

Barmar
Barmar

Reputation: 782693

response.json(...)

this inside the function is equal to the value of response.

When you use the OR version, it's equivalent to:

tempfn = returning || response.json;
tempfn({message: 'ok', account});

Calling tempfn doesn't bind the this variable to anything, so it defaults to the global object.

The response.json function presumably needs access to the response object, so it fails when you don't bind it correctly.

You can get what you want by calling .bind() explicitly:

newToken(account, request, response, returning = false) {
  /* Irrelevant code ommitted */
    return Promise.resolve((returning || response.json.bind(response))({message: 'ok', account}))
}

Upvotes: 2

Related Questions