Skip to content

!fullResponse?.response?.is_complete does not act as it supposed to do

I am having an issue to understand this:

!fullResponse?.response?.is_complete

I was thinking it is the same as

        fullResponse &&
      fullResponse.response &&
      'is_complete' in fullResponse.response &&
      !fullResponse.response.is_complete

but it is not and it breaks my code specially when is_complete does not present in fullResponse.response

Can anyone explain what this does : !fullResponse?.response?.is_complete and if there is a way to make it act as below?

            fullResponse &&
      fullResponse.response &&
      'is_complete' in fullResponse.response &&
      !fullResponse.response.is_complete

Answer

The part you’ve probably misunderstood is the precedence of these operators. Your code actually boils down to:

!(
  //            vvvvvvv--- `== null`: either null or undefined
  (fullResponse == null) ? undefined
  :(fullResponse.response == null) ? undefined
  :fullResponse.response.is_complete
)

So, when either part of your lookup short-circuits with an undefined, it runs right into the negation and gets converted to true.

If you just want to return false in case of a short-circuit, then it’s as easy as:

//                                       vvvv--- this will turn into false
!(fullResponse?.response?.is_complete ?? true)

However, if you want undefined in this case, it’s easier with a variable:

const isComplete = fullResponse?.response?.is_complete
isComplete === undefined ? undefined : !isComplete

If you can’t do that, you’ll have to repeat the lookup:

fullResponse?.response?.is_complete === undefined ? undefined : !fullResponse?.response?.is_complete