Ternary not working correctly in array .find method JavaScript

I encountered some perplexing behavior in using a ternary within the .find method of an array. When searching for an object:

Consider this:

const list = [
  { id: 1, name: "dave"},
  { id: 3, name: "choi"},
  {id: 4, name: "bob"}
]

// this works
let isBoy = true
console.log(list.find(v => v.name === isBoy ? "dave" : "choi"))


// this don't work
isBoy = false
console.log(list.find(v => v.name === isBoy ? "dave" : "choi"))

// this always works: use () around ternary
console.log(list.find(v => v.name === (isBoy ? "dave" : "choi")))
isBoy = true
console.log(list.find(v => v.name === (isBoy ? "dave" : "choi")))

What surprised me was that

// this don't work
isBoy = false
console.log(list.find(v => v.name === isBoy ? "dave" : "choi"))

It will return "dave" instead of "choi". This was the cause of a recently very hard to find bug today. Can anyone elucidate what is going on here and why this is expected behavior?

Why does the parenthesis matter? What should I read up on to understand this better? Is this an order of operations thing? My javascript IDE linter did not complain or warn about this which it usually does when vague order of operations stuff.

What I tried

I tried searching for SA questions similar to mine that might shed light on this problem but didn’t find anything that explained what I was seeing.

>Solution :

The problem is operator precedence. Comparison operators have higher precedence than than ternary (since it’s common to use comparisons in the condition), so your code is interpreted as:

list.find(v => (v.name === isBoy) ? "dave" : "choi")

You need to add parentheses to get what you intend:

list.find(v => v.name === (isBoy ? "dave" : "choi"))

Leave a Reply