Potential `undefined` Object Error Encountered with Optional Chaining in TypeScript

Currently, I have a response that I am retrieving from:

data?.currentOrganization?.onboardingSteps?
. It is possible for data, currentOrganization, and onboardingSteps to be null. My goal is to create a variable like this:

const hasSteps = data?.currentOrganization?.onboardingSteps?.length > 0;

My expectation was that hasValue would be false if any of the fields were null or if there were less than 1 step. However, I encountered the TypeScript error: Object is possibly 'undefined'.

To work around this issue, I currently have:

const hasSteps =
  data?.currentOrganization?.onboardingSteps != null &&
  data?.currentOrganization?.onboardingSteps?.length > 0;

Although it works, I find this approach overly verbose. Is there a more elegant alternative solution available?

Answer №1

When using the optional chaining feature, the resulting value for

data?.currentOrganization?.onboardingSteps?.length
will be a number only if all parts of the chain are not null or undefined. If any part is nullish, then the output will be undefined. Trying to compare undefined > 0 will trigger an error in Typescript.

To handle this situation, it's recommended to do something like the following:

const hasSteps = (data?.currentOrganization?.onboardingSteps?.length ?? 0) > 0;

This code snippet utilizes nullish coalescing to assign a default value of 0 if the optional chain results in undefined.

Link to Playground for testing

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

Out of the box, Next.js is equipped with a standard error message stating: "TypeError: Cannot read properties of null (reading 'useContext')"

After just setting up next.js for my upcoming website, I ran into some unexpected errors while trying to host it with "next". The specific error message I encountered was: TypeError: Cannot read properties of null (reading 'useContext') This iss ...

What is the best way to begin at a specific index in an array without skipping any elements?

As I continue my journey of learning JS, I have encountered a task that has left me quite perplexed. The objective is to provide an index to start from and also include the items missing in the array while displaying them in an angular format. Here is what ...

JavaScript quiz featuring randomized questions with selectable radio buttons

I need assistance in creating a feature on my webpage where users can select the number of questions they want to answer (ranging from 1 to 10). The selected number of questions should then be displayed randomly, without any duplicates. I am not very famil ...

What is the best way to deactivate buttons with AngularJS?

I have a situation where I need to disable the save button in one function and permanently disable both the save as draft and save buttons in another function using AngularJS. How can I accomplish this task with the disable functionality in AngularJS? Her ...

Ways to substitute EACH word in JQuery or JavaScript?

I've been attempting to substitute each word in a passage with another, but I haven't come across any method of achieving this. Here's an example: from this> Hello, my name is Robert. to this> Greetings Greetings Greetings Greetings ...

Exploring Data Source in Angular through Iteration

I am looking to create a function that will loop through an array of objects and update the status property to false. This array of objects is being used as a data source in an Angular table. this.lightService.getLamp() .subscribe( (response) => ...

Node.js alternative for PHP include in markup

Looking for a way to include PHP functionality in NodeJS/Express markup without using a full template engine like jade? Check out this interesting question: Nodejs Include Other Views? I'm in need of similar functionality, but I'm not keen on le ...

Comparing Nodes Armed with Clusters to Nodes Sporting Threads

Can you explain the key distinctions between node cluster and Threads agogo, including their respective advantages and disadvantages? From my understanding, Threads agogo creates a background thread while node cluster initiates a new process to run in th ...

What is the recommended life cycle method to use with Redux?

What is the recommended approach for accessing data from the redux store in props? ...

Mobile website scroll assistant

Seeking a solution to aid mobile users in scrolling through a lengthy article page. Typically in mobile apps, an alphabetical index assists users in navigating long lists. How can I incorporate a similar feature into a webapp? For context, my tech stack i ...

How to access JSON variable containing a point in AngularJS

Currently utilizing Sequelize, I have successfully executed an Inner Join after multiple attempts and achieved satisfying results: { "success": false, "message": "Query not successful, the result was empty", "data": { "codWO": "1016285 ...

Using React's useEffect function with an empty dependency array to trigger a change in the

In the React application I'm currently working on, the useEffect function is triggered whenever the prop value changes from an empty array to another empty array. I am fetching query parameters from the page and passing them down to a component that ...

I encountered a permission denied error when trying to enter DEBUG=app ./bin/www in Node.js

After renaming 'my-application' to just 'app', I encountered an issue when running the DEBUG command in the terminal: I used DEBUG=app ./bin/www Originally, it was named 'my-application' as created by express. However, after ...

Secure mustache templates for data validation

Is there a method to achieve the following?: my-custom-template.mstach Hello {{name}}! script.js import { readFileSync, writeFileSync } from 'fs'; import * as Mustache from 'mustache'; export interface Person { name: string; } ...

I keep running into a problem that says "Uncaught TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))". I've been unable to come up with a solution so far

const Header = () => { const firebaseAuth = getAuth(app); const provider = new GoogleAuthProvider(); const [{user}, dispatch] = useStateValue(); const login = async () =>{ const { user: { refreshToken, providerData }, } = await sign ...

Get ready for 10 AM with the RxJS timer function

I am trying to figure out how to schedule a method in my code using rxjs/timer. Specifically, I want the method to run at precisely 10 AM after an initial delay of 1 minute. However, my current implementation is running every 2 minutes after a 1-minute d ...

The functionality of scrolling in Angular Material tabs is not functioning properly

I have encountered a challenge while working with angularjs material design. The md-scroll functionality is not working as expected for scrolling up and down, even though it works fine for left and right scrolling. In a tab with a table view, the vertical ...

What is the best way to sign up for input so that any modifications are automatically saved to an object?

My HTML form input looks like this: <mat-form-field appearance="fill"> <mat-label>Flowrate: </mat-label> <input id = "flowRate" type="number" matInput> </mat-form-field> In my .ts file ...

Tips for resolving the issue when encountering an unknown error message at useSelector: Unhandled Promise Rejection: TypeError: useSyncExternalStore is not defined

Encountered the following error : Unhandled Promise Rejection: TypeError: useSyncExternalStore is not a function. (In 'useSyncExternalStore(subscribe, getSelection, getServerSelection)', 'useSyncExternalStore' is undefined) https://i.s ...

What methods can be used to prevent divs from overlapping when the window size is reduced?

Creating a login page with two main content divs in a section layout. The first div contains the logo, input prompts, and login/password reset buttons. The second div serves as a footer with social media links. On a full-size window, the logo is positioned ...