Utilizing optional chaining in TypeScript when employing the bracket syntax for finding by key

In my code, I'm experimenting with the optional chaining operator in this scenario:

productPrice1: product.prices["1"]?.amount.amount_1,

By using the question mark as shown above, I ensure that if there is no child object with key ["1"], it won't result in an error. However, now I am looking to extend this feature to also handle cases where the parent object prices does not exist.

The prices object contains child objects with keys like "1", "2", and "3. My goal is to first verify if prices is null, and then only check if ["1"] exists if prices itself is defined.

I initially tried to implement this logic but encountered issues:

productPrice1: product.prices?["1"]?.amount.amount_1,

I want to find a way around explicitly checking for null and wondering if there's a better approach than what I have done here:

productPrice1: product.prices != null ? product.prices?["1"]?.amount.amount_1 : null,

Answer №1

Let's assume that your product value is structured as follows:

declare const product: {
    prices?: Partial<Record<"1" | "2" | "3",
        {
            amount: {
                amount_1: number
            }
        }>>
}

In this case, you can implement optional chaining in the following manner:

const val = {
    productPrice1: product.prices?.["1"]?.amount.amount_1
}

An important detail to remember is that even when you are not using dotted property access, the syntax for optional chaining is always ?. with the dot. The tc39 proposal on optional chaining emphasizes this:

The Optional Chaining operator is spelled ?.. It may appear in three positions:

 obj?.prop       // optional static property access
  <b>obj?.[expr]     // optional dynamic property access</b>
  func?.(...args) // optional function or method call

It might seem odd, but according to the FAQ of the proposal (link):

obj?.[expr] and func?.(arg) look ugly. Why not use obj?[expr] and func?(arg) like <language X>?

We don’t use the obj?[expr] and func?(arg) syntax because it could confuse the parser with the conditional operator, example:
obj?[expr].filter(fun):0,
func?(x - 2) + 3 :1.

While different syntaxes were considered, the decision was made based on readability and efficiency for common cases like obj?.prop; hence, the use of ?. for consistency.

Feel free to explore the TypeScript playground link to experiment with the code.

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

What is the rationale behind sending only one form?

Is there a way to send two forms with just one click? The first form uploads an image to the server, while the second form sends information to a database. However, only the "myform" seems to be sent. Any suggestions? <form action="uploadpic.php" met ...

What is the best way to automatically close a parent popup window when the child popup is

Currently, I am developing a web application using Angular that requires managing nested popups. Specifically, in my scenario, I initiate Popup 1 and from within that popup, I trigger another popup (Popup 2) upon clicking "delete." My goal is to ensure tha ...

Utilizing webpack to import both d3 and d3-cloud libraries

I've been attempting to integrate d3 and d3-cloud (for word cloud) into my AngularJs(v - 1.4) app by using: import d3 from 'd3' import d3Cloud from 'd3-cloud'. However, when trying to use d3-cloud with d3.layout.cloud(), ...

Issue with Angular 17 button click functionality not functioning as expected

Having trouble with a button that should trigger the function fun(). Here's the code snippet I'm using. In my TS file: fun(): void { this.test = 'You are my hero!'; alert('hello') } Here is the respective HTML: &l ...

Triggering Jquery event multiple times

I am using a jQuery datatable that gets populated with data from a database through an AJAX call when a user clicks on a load button. The data is displayed based on the date selected by the user in a datepicker. I have also added an export button to allow ...

Dealing with Firebase Range Queries Results

Hello, I am currently working on managing responses from a Firebase REST service as outlined in https://firebase.google.com/docs/database/rest/retrieve-data. Below is an example of the response I am getting: { "2": { "name": "John", "surname": " ...

The type 'function that takes in a CustomEvent and returns void' cannot be assigned to a parameter of type 'EventListenerOrEventListenerObject'

When I upgraded from TypeScript version 2.5.3 to 2.6.1, my custom event setup started giving me an error. window.addEventListener('OnRewards', (e: CustomEvent) => { // my code here }) [ts] Argument of type '(e: CustomEvent) => ...

Guide on implementing an onClick event for rows in an Angular Mat-Table and navigating to a separate page

I'm seeking guidance on how to implement a click event for a specific row that will navigate to the next form while carrying over the values of the clicked row. I find this concept a bit perplexing at the moment. <!-- Position C ...

What methods can be used to identify if a browser is mobile and adjust the size of a video accordingly using JavaScript conditions?

My goal is to incorporate JavaScript and jQuery into my HTML page in order to detect if visitors are using mobile browsers, and display a video at different sizes based on this information. I have experimented with various methods, but none of them have p ...

Ensure that the header stands out by creating a grey background for the rest

https://i.sstatic.net/XUCkS.png Is there a way to change the background color of this layout to grey, excluding the top bar and bottom footer? The layout is structured like this: <html> <head> <body> <div id="big_wrapper"> ...

What is the best way to retrieve data from a database and display it in a select dropdown list

I'm working on creating a Bingo game and I want to include a dropdown list that displays my previous records. How can I retrieve data from a database to populate this select dropdown list? Below is the relevant code snippet in PHP: <html> < ...

Guide on how to trigger the md-menu to open using mouse hover

I'm in the process of using Material 2 to design a menu. I have a md-button that triggers the opening of a md-menu and I want it to open when hovered over. Since Material Angular.io is still relatively new, I've searched for solutions online but ...

How do I access the previous and current values in a v-for loop in Vue.js in order to compare them?

I am working on a structural component that involves looping through a list and performing certain actions based on the items: .... <template v-for="(item, INDEX) in someList"> <template v-if="thisIsArrayList(item)"> ...

Troubleshooting in Angular 7: When Auth0 parseHash response is returning null

Having trouble with Auth0. Upon sign-out and browser refresh, my application is unexpectedly triggering the login event again and encountering user profile issues. The root of the problem seems to lie in the parseHash method within the authentication serv ...

Running and halting multiple intervals in Javascript - a guide

Imagine a scenario where I am setting up 3 intervals with times of 500ms, 1s, and 1.5s. When I click on the button for the 500ms interval, I want to stop the other two intervals and only run the 500ms one. The same goes for clicking on the 1s or 1.5s butto ...

I am currently developing an application that can produce random video game suggestions and display the corresponding game cover upon generation

I'm facing an issue with displaying the video game cover image from my HTML document when the game title is generated using a JavaScript function. I have searched online for solutions, but couldn't find anything similar to my problem. Here is my ...

Preventing bubbling and propagation in Ember 2.x

Is there a specific method to prevent event bubbling in Ember 2.18 in this particular situation? I couldn't find a matching example in the official documentation, but I did come across two alternative solutions on other websites. Both of them seem to ...

Script for tracking user activity on Facebook and Google platforms

I currently have Google tracking conversion set up, but now I also need to implement Facebook pixel tracking. My existing Google Head Script code is as follows: <script> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||fu ...

The MSAL HTTP_INTERCEPTORS fail to include the request headers seamlessly

Currently, I am in the process of integrating MSAL authentication into my Angular application. The login process at the start is working smoothly with Azure AD. In addition to that, I have included msal_interceptor as a provider in my app.module provider ...

Encountering the error message "Received interpolation ({{}}) when an expression was expected" is a common issue when trying to interpolate tag attribute values within an ngFor loop

I've been working with a Devextreme's Datatable and my goal is to dynamically configure the table using a columns configuration array. The plan is to loop through this array using an ngFor and set column tags properties dynamically. Now, the bi ...