-1

I want to check if a property exists in my object or not, If it exists I want to add a number to it and if it doesn't I want to create a property and set the value to 1. I did everything and i used optional chaining and logical assignment but there is an error it says: Uncaught SyntaxError: Invalid left-hand side expression in postfix operation can you say whats the problem? here is the code:

const scores = {};
for (const player of Object.values(game.scored)) {
  scores?.[player]++ && scores[player] = 1;
}

note: game.scored contains 4 names;

i did my best, i could do it with ternary operator and it worked but i want to know why it doesn't work with optional chaining and logical assignment

  • Well first, using `&&` like that will evaluate _both_ conditions, so if this works at all and a score already exists, it would increment the score and then set it to `1` — you'd want to use `||` so if the left side increments the _or_ condition is satisfied and the right side won't be evaluated. – Stephen P Aug 22 '23 at 18:38
  • 2
    You're probably after [optional **assignment**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_assignment) not optional chaining: `scores[player] ??= 0; scores[player] += 1;` – VLAZ Aug 22 '23 at 18:45
  • Please see [ask], then revise your post title to ask a clear, specific question. Don't tack on tags. – isherwood Aug 22 '23 at 18:50

2 Answers2

1

You can't assign to an optionally chained expression; they can't appear on the "left-hand side" of an assignment.

This would require something like this to work:

a?.foo = 1

How is this supposed to work when a is null? You'd effectively be producing the statement undefined = 1.

In your case you're expecting this to work:

 scores?.[player] = scores?.[player] + 1

What happens if scores is null? You end up with undefined = undefined + 1, neither the left-hand or right-hand side of that assignment make sense.


Note that, the whole thing is written incorrectly, and it makes no sense to write scores?.[player] when you've just assigned scores = {} two lines up. scores?.[player] checks whether scores is null, not whether scores[player] is null.

You're trying to test whether the key player is already in the object scores, which is here: How to check if object property exists with a variable holding the property name?

user229044
  • 232,980
  • 40
  • 330
  • 338
  • thank you but i have another question how does this work? scores[player] ? scores[player]++ : (scores[player] = 1); now scores[player] is undefiend and i set it to 1 in other code I add 1 to the value but if it's undefiend js will run the right side and in the right side I set it to 1 like this one. but if it's not undefiend it just add 1 to it. – parsa_keshavarzi Aug 22 '23 at 18:51
  • @parsa_keshavarzi I don't really follow your question. `scores[player] ? scores[player]++ : scores[player] = 1` works just fine. As written, it's no different from the equivalent `if`/`else` which should be self-explanatory. – user229044 Aug 22 '23 at 18:53
0
  scores[player] = (scores[player] ?? 0) + 1;

here, (scores[player] ?? 0) checks if the left expression is null, and if so it returns the one on the right, otherwise it'll return the one on the left. Therefore scores[player] will be assigned scores[player] + 1 when it already exists, and be created and assigned a 1 when it doesn't. HIH