1

Being that in Javascript optional chaining on the left side of an assignment is not possible, as noted in this question and answer, what are some possible alternative methods to achieve this?

customer.details?.car = { make: 'Toyta' }
  1. I know you can do that with an if

    if (customer.details) {
        customer.details.car = { make: 'Toyota' };
    } else {
        customer.details = { car: { make: 'Toyota' } };
    }
    
  2. I tried with Logical OR || but I'm not sure it's possible and the below is not correct

    customer.(details || {}).car = { make: 'Toyota' };
    
  3. Ternary with spread works (with help from @garrettmills)

    customer.details = customer.details 
        ? { ...customer.details, car: { make: 'Toyota' } }
        : { details: { car: { make: 'Toyota' } } };
    

Are there any other methods?

shmuels
  • 1,039
  • 1
  • 9
  • 22

2 Answers2

2

You're looking for logical nullish assignment, the short form of x = x ?? y:

(customer.details ??= {}).car = { make: 'Toyota' };

It also works nice with chaining, e.g.

((customer.details ??= {}).car ??= {}).make = 'Toyota';
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
1

I prefer:

customer.details = {
    ...(customer.details || {}),
    car: { make: 'toyota' },
}

since it implies that you are "overlaying" details with a new property.

It's worth noting that your example (3) doesn't seem to work quite right. If the customer already has a details field, then the entire customer record will be replaced with { details: { car: ... } }.

garrettmills
  • 660
  • 6
  • 13