0

I don't understand the behavior I have in my condition. I try to reduce the code as much as possible. With this condition I want to know if r.user.id or r.user.uid is equal to getUser.uid. https://jsbin.com/zakofusiga/edit?js,console

let getUser = { uid: "123" };
let r = { user: { id: "toto", uid: "123"}}

if (r.user && (r.user?.id === getUser?.uid || r.user?.uid === getUser?.uid)) { ... }

To do so I made this code so below. It works but I don't understand why r?.user?.id||uid === getUser?.uid me returns toto is not a boolean. Does this code work like the one above?

if (r?.user?.id||uid === getUser?.uid) {
  console.log("test 1", r?.user?.id||uid === getUser?.uid);
}

if (r.user?.id === getUser?.uid) {
  console.log("test 2");
}
               
if (r.user?.uid === getUser?.uid) {
  console.log("test 3");
}
DenisMasot
  • 697
  • 5
  • 11
  • 21
  • 1
    What is `r?.user?.id||uid === getUser?.uid` supposed to be? It's currently `r?.user?.id || (uid === getUser?.uid)` ([see here for what it does](https://stackoverflow.com/q/9579262)). Did you mean `(r?.user?.id || uid) === getUser?.uid` or something else? And what's `uid`? – VLAZ Oct 19 '20 at 12:48
  • 1
    You could destructure the nested user `const { id, uid } = r.user ?? {}` and then use `if (r.user && [id,uid].includes(getUser?.uid) )` – adiga Oct 19 '20 at 12:53
  • Also there is no need to do optional chaining in `r.user?.id` since you are already checking `r.user` before – adiga Oct 19 '20 at 12:56
  • What's the point of adding a question mark after `getUser`? Isn't `getUser` always defined? The same for `r?`. – axiac Oct 19 '20 at 12:59
  • What do you want to achieve? Do you want to verify that `getUser.uid` is equal to `r.user.id` or to `r.user.uid` (the first one that exists)? – axiac Oct 19 '20 at 13:00
  • With this condition I want to know if `r.user.id` or `r.user.uid` is equal to `getUser.uid` – DenisMasot Oct 19 '20 at 13:12

3 Answers3

1

As VLAZ said, ||| isn't the logical OR operator, it's a syntax error. (It looks like the logical OR operator [||] followed by the bitwise OR operator [|], but you can't do that because you need an operand between them). You want just || (the logical OR operator).

I'm assuming in your real code r.user may be undefined or null (and similarly for getUser), otherwise all those optional chaining operators are unnecessary.

r.user?.id will be undefined if r.user is undefined or null. So will getUser?.uid (if getUser is undefined or null). Assuming you don't want to match in the undefined case, you'll need to check for that.

Given that, your first example is probably as concise as it's going to get, or perhaps more explicitly:

if (r.user?.id !== undefined && (r.user?.id === getUser?.uid || r.user?.uid === getUser?.uid)) {
    // ...
}

Or you might consider adding a variable:

const gid = getUser?.uid;
if (gid !== undefined && (r.user?.id === gid || r.user?.uid === gid)) {
    // ...
}

Add a ? after r if r itself may be undefined or null.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

Your conditions are too many and unnecessarily complicated. It's not clear for me what do you want to achieve with this code, so I assume its purpose is to verify that getUser.uid is equal to r.user.id or r.user.uid (the first one that exists).

I would extract the two values in two variables:

const id1 = getUser.uid;
const id2 = r.user?.id || r.user?.uid;

Here id1 is either getUser.uid (if getUser has the property uid) or undefined otherwise.

id2 is the first one that matches:

  • r.user.id, if r has the property user that is an object having the property id;
  • r.user.uid, if r.user does not have id but has uid;
  • undefined if r does not have user or r has user but r.user does not have id and uid.

Now all you have to do is to compare id1 to id2, possibly with a guard against undefined:

if (id1 !== undefined && id1 === id2) {
  console.log('yes!');
}
axiac
  • 68,258
  • 9
  • 99
  • 134
  • 1
    if both `r.user.id` and `r.user.uid` should be compared against `getUser.uid`, you cannot simply compare "`id2` is the _first_ one that matches..." You have to check both. – Mulan Oct 19 '20 at 13:19
  • "Both" means `&&`. The code in the question uses `||`. – axiac Oct 19 '20 at 16:18
0

I would suggest -

function userMatches (getUser, r)
{ if (getUser && r?.user)
    return r.user.id === getUser.uid
        || r.user.uid === getUser.uid
  else
    return false
}

Or using default arguments, something like -

const userMatches = ({ uid = 0 }, { user = {} }) =>
  user.id === uid || user.uid === uid
Mulan
  • 129,518
  • 31
  • 228
  • 259