0

In JavaScript, is it possible to do something akin to an optional chain on Array.find? I.e., like in the (incorrect) example below?

let myArray = [{name: "foo", value: 30}, {name: "abc", value: 40}];
myArray.find(entry => entry.name === 'foo')?.value = 50;

I tried the above syntax, but it throws an error, and I was wondering if there is some neat one-line way to achieve this without having to declare another variable to store the Array.find result and check if it is truthy before you can set value = 50.

4 Answers4

1

No it's not possible. You can only use optional chaining for reading values.

Optional chaining (?.)

The optional chaining operator (?.) enables you to read the value of a property located deep within a chain of connected objects without having to check that each reference in the chain is valid.

source

If you don't want to declare an extra variable you could call the same method twice, combined by a && in order to check if value has a value, as a workaround:

let myArray = [
  { name: "foo", value: 30 },
  { name: "abc", value: 40 },
];
myArray.find((entry) => entry.name === "foo").value &&
  (myArray.find((entry) => entry.name === "foo").value = 50);

console.log(myArray);

Another variant is to just try force setting a value...

let myArray = [
  { name: "foo", value: 30 },
  { name: "abc", value: 40 },
];

try { myArray.find((entry) => entry.name === "foo").value = 50; } catch {}
try { myArray.find((entry) => entry.name === "notfound").value = 50; } catch {}

console.log(myArray);

But neither are good options.

Behemoth
  • 5,389
  • 4
  • 16
  • 40
1

When you do:

({a:1})?.a = 10

What you are really doing is:

1 = 10

Which causes the same error as you have observed. So you cannot use optional chaining to set values.

Assuming you want to mutate the element of an array what you could do is use ?? to default to empty object in case Array#find returns null. If an element is found you can modify it, if not you're just assigning 50 to an object that is immediately discarded:

let myArray = [{name: "foo", value: 30}, {name: "abc", value: 40}];
(myArray.find(entry => entry.name === 'foo') ?? {}).value = 50;
customcommander
  • 17,580
  • 5
  • 58
  • 84
0

You can not use optional chaining to set values. It is only used to get values.

Charles Barnes
  • 100
  • 1
  • 8
0

You can use like this if you really need to assign value by reference with one line without a variable:

Object.assign(myArray.find(entry => entry.name === 'foo') ?? {}, {value: 50})

But it's dirty

Floyd
  • 367
  • 2
  • 5