Using optional chaining on the left side in JavaScript is a convenient feature

Can the optional chaining operator be used on the left side of an assignment (=) in JavaScript?

const building = {}
building?.floor?.apartment?.number = 3; // Is this functionality supported?

Answer №1

There's a current proposal (in stage 1) that aims to provide support for it: Check out the proposal here


Unfortunately, it is not feasible at this time.

For further clarification, although the MDN documentation does not explicitly mention it, you can refer to the proposal's README on GitHub to gain more insight. The proposal mentions:

The following feature is currently not supported, despite having potential use cases; please refer to Issue #18 for further discussions:

  • Optional property assignment: a?.b = c

The mentioned issue includes comments like 1:

Looks like there is a general agreement in this thread to exclude the write case initially.

and 2:

This matter was also put forth to TC39 for discussion, and it appears that the committee may not be keen on incorporating this particular feature.

Consequently, it seems unlikely to be implemented in the near future.

We hope this sheds some light on the topic; best wishes!

Answer №2

After delving into it myself, I found that unfortunately, like others have pointed out, performing an assignment using optional chaining seems to be impossible in TypeScript at the moment of writing, resulting in a parser warning:

The left side of an assignment expression cannot be an optional property access.

If you try something like this:

class A{
    b?: string;
}

var a = new A();
a?.b = "foo";

However, since optional assignments can be beneficial, there is still the traditional approach of using single-line if-else queries like this:

class A{
    b?: string;
}

try{a.b = "foo0"} // throws TypeError
catch(e){console.log(e.toString())} // a is undefined

if(a) a.b = "foo1"; // skips
console.log(a); // a is undefined

var a: any;
if(a) a.b = "foo2"; // skips
console.log(a); // a is undefined

a = null;
if(a) a.b = "foo3"; // skips
console.log(a); // a is null

a = undefined;
if(a) a.b = "foo4"; // skips
console.log(a); // a is undefined

a = new A();
if(a) a.b = "foo5"; // runs
console.log(a); // a is A: {"b": "foo5"}

if(null) console.log("bar0"); // skips
if(undefined) console.log("bar1"); // skips
if({}) console.log("bar2"); // runs
if({something: "there"}) console.log("bar3"); // runs
if([]) console.log("bar4"); // runs
if(["not empty"]) console.log("bar5"); // runs

For an example where this is achievable, here's a Kotlin code snippet:

class A{
    var b: B? = null;
    var title: String? = null;
    override fun toString():String = "Instance of class A with title: ${this.title} and b of value: ${this.b.toString()}";
}

class B{
    var title: String? = null;
    override fun toString():String = "Instance of class B with title: ${this.title}";
}

fun main() {
    var a:A? = null;
    println(a); // null
    
    try{a!!.title = "foo0"} catch(e:Exception){println(e)} // NPE
    
    a?.title = "foo1";
    println(a); // null
    
    a = A();
    println(a); // Instance of class A with title: null and b of value: null
    
    a?.title = "foo2";
    println(a); // Instance of class A with title: foo2 and b of value: null
    
    try{a!!.b!!.title = "bar0"} catch(e:Exception){println(e)} // NPE
    
    a?.b?.title = "bar1";
    println(a); // Instance of class A with title: foo2 and b of value: null
    
    a?.b = B();
    println(a); // Instance of class A with title: foo2 and b of value: Instance of class B with title: null
    
    a?.b?.title = "bar2";
    println(a); // Instance of class A with title: foo2 and b of value: Instance of class B with title: bar2

    a?.b?.let{it.title = "bar3"}
    println(a); // Instance of class A with title: foo2 and b of value: Instance of class B with title: bar3
}

I'm not trying to argue for one language over another, but simply highlighting how different purposes and philosophies influence design choices, shaping the tools that programming or scripting languages ultimately become. It's just slightly frustrating that assigning values to an optional chain isn't possible in TypeScript.

Edit: I used these Playground sites to experiment with such scenarios:

Answer №3

At this moment, achieving this task is not feasible. However, there are alternative methods you can explore.

For example:

let a = {x: {y: {z: 2}}} as {x?: {y?: {z?: number}}};
a?.x?.y?.z ? a.x.y.z = 1 : null;

Another option is to utilize lodash library:

let a = {}
_.set(a, 'x.y.z', 1);
_.get(a, 'x.y.z');

Answer №4

Sorry, but that is not an option. According to the official documentation,

The optional chaining operator ?. allows for easy accessing of a property deep within a series of interconnected objects without needing to verify each reference in the chain.

Answer №5

Instead of directly setting the number to 3, you could try this approach:

(((structure ?? {}).level ?? {}).unit ?? {}).quantity = 3;

By doing this, it will essentially undo the assignment by creating a temporary object if any of the preceding objects don't actually exist.

Remember that the right side of the expression will be executed regardless of whether the left side is temporary or not. To prevent this, you can add a condition before assigning the value:

if (structure?.level?.unit)
    structure.level.unit.quantity = 3;

(Keep in mind that this condition assumes unit, if present, must be an object...)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Modify/Adjust/Move the image uploaded by the user in VueJS before transferring it to an aws s3 bucket

Can you resize images in vuejs using vanilla js? I've managed to upload an image and send it to my s3 bucket using vue, but I'm struggling to figure out how to transform an image within vuejs and display it. Document.querySelector doesn't se ...

The specified function 'isFakeTouchstartFromScreenReader' could not be located within the '@angular/cdk/a11y' library

I encountered the following errors unexpectedly while working on my Angular 11 project: Error: ./node_modules/@angular/material/fesm2015/core.js 1091:45-77 "export 'isFakeTouchstartFromScreenReader' was not found in '@angular/cdk/a11y&a ...

Storing data in a TypeBuffer and then retrieving it from a file can lead to surprising outcomes

Upon executing the following code: var list = new Uint32Array(16); for (var i=0; i<16; ++i) list[i] = i; fs.writeFileSync("list", new Uint8Array(list).buffer); console.log([].slice.call(new Uint32Array(fs.readFileSync("list")))); We anticipate the out ...

Is there a Wordpress floating bar similar to the one seen on 9gag?

After browsing through some posts on stackoverflow, I noticed that my website is not responding as expected. You can check out my site here: To troubleshoot, you can examine the source code and utilize Firebug to inspect the css and javascript being used ...

Converting rotation into a directional vector

I have a Three.js object and I am able to read its rotation. However, I am looking for a way to extract a vec3 that indicates the direction in which the object is currently rotated. Can someone provide guidance on how to achieve this? ...

Retrieve all services within a Fargate Cluster using AWS CDK

Is there a way to retrieve all Services using the Cluster construct in AWS CDK (example in TypeScript but any language)? Here is an example: import { Cluster, FargateService } from '@aws-cdk/aws-ecs'; private updateClusterServices(cluster: Clus ...

Contrast the differences between arrays and inserting data into specific index positions

In this scenario, I have two arrays structured as follows: arr1=[{room_no:1,bed_no:'1A'}, {room_no:1,bed_no:'1B'}, {room_no:2,bed_no:'2A'}, {room_no:3,bed_no:'3A'}, {room_no:3,bed_no:'3B ...

JQuery UI autocomplete vanishes instantly without any warning

I am encountering an issue with JQuery UI's autocomplete feature where the dropdown results do not stay visible. While debugging, I noticed that the list briefly appears before disappearing. Below is my code snippet: HTML: <input type="text" plac ...

Create interactive highcharts graphs using data from a CSV file generated through PHP

I'm having trouble working with Highcharts and csv data. Take a look at this example: http://jsfiddle.net/gh/get/jquery/1.9.1/highslide-software/highcharts.com/tree/master/samples/highcharts/demo/line-ajax/ $.getJSON('http://www.highcharts.com/ ...

a guide on configuring a default input value from a database in a React component

In my current project, I have an input field with the type of "checkout" and I am looking to utilize Firestore to retrieve a default value. Once I obtain this value, I plan to store it in the state so that it can be modified and updated as needed. Here i ...

External API data is shown in the browser console but appears as undefined on the page

Can you please lend me a helping hand? I am facing a critical issue while attempting to retrieve data from an external API using axios in NextJS (Reactjs)/TypeScript through getServerSideProps. The data fetching is successful, and the JSON is returned on t ...

Ways to programmatically append data to an object using JavaScript

My dilemma involves an object: var myObject={}; accompanied by a function that appends values to the object: function appendData(id, name){ //logic to validate id and name format, specify conditions for name being "John" and id being "I23423" my ...

When exporting a custom ES6 module and importing it into a different local project, you may encounter unexpected outputs such as being undefined or

Currently, I am using TypeScript 3.4.5 and Webpack 4.32.2 on Windows 10 via WSL. My goal is to create a local package of tools that consolidates basic classes into an index file for exporting. However, when I try to import these classes into other project ...

PHP code in Wordpress incorporating an Ajax request

Does anyone know how to fetch user data as a string using ajax in WordPress? I think I understand the basic concept PHP This code goes in my functions.php file add_action('template_redirect', 'edit_user_concept'); function edit ...

Guide to incorporating JSON data into HTML through JavaScript

As I attempt to load data from a JSON file to .js and then to an HTML file, I am facing a challenge. While I can successfully load the JSON values into .js, I am unable to transfer the same values to HTML. Below is the code snippet - could anyone provide a ...

Is it possible for me to generate values using PHP that can be easily read by JavaScript?

I'm currently building a website and I am facing some challenges when trying to incorporate JavaScript for real-time calculations. Here are my issues: Is there a more efficient way to avoid manually typing out the code for each level up to 90, lik ...

Error: The specified file or directory does not exist at location 'D:E-commerceJsfrontend ode_modules.axios.DELETE'

As I work on my e-commerce project using vanilla JavaScript and webpack with npm, I keep encountering an issue while trying to install axios. npm ERR! enoent ENOENT: no such file or directory, rename 'D:\E-commerceJs\frontend\node_mod ...

Error occurs when attempting to access window.google in Next.js due to a TypeError

I've been working on integrating the Google Sign In feature into my Next app. Here's how I approached it. In _document.js import React from 'react'; import Document, {Html, Head, Main, NextScript } from 'next/document'; expo ...

Showing information from a JSON dataset of users once a specific User ID has been chosen

My task involves displaying user data from an array and then showing the details of the selected user. I attempted to achieve this with the following code: users = USERS; // contains data selectedUser: User; constructor() { } ngOnInit() { } onSelect(i ...

Dealing with the issue of receiving raw JavaScript in the .ajax error function even when receiving a 200

I am encountering an issue with a jQuery.ajax() call to a third-party product. The POST request is successful, returning a 200 OK status code, but instead of executing the success function, it redirects to the error function. The response variable displays ...