Exploring the attributes of optional features

Dealing with optional properties can be quite tedious. Consider the object test1 in TypeScript:

interface Test {
    a?: { b?: { c?: { d?: string } } };
}

const test1: Test = { a: { b: { c: { d: 'e' } } } };

Handling the absence of each property is crucial to avoid errors when trying to access the value 'e'. For example:

let result;
const test2: Test = { a: { b: {} } };

Directly accessing the property d will throw an error if c is undefined, as it does not have the property d:

result = test2.a.b.c.d // TypeError: undefined is not an object

Manually checking each property is necessary:

let result;
if (test2 && test2.a && test2.a.b && test2.a.b.c && test2.a.b.c.d !== undefined) {
    result = test2.a.b.c.d;
}

What is the most efficient and best practice approach to tackle this common issue?

Using a try/catch block is an option, but it may not be the shortest solution. Passing test2.a.b.c.d as a function argument to handle the error also seems problematic, as the error would occur before the function is executed.

Answer №1

For a long time, I followed a lengthy process until today when I devised a concise solution utilizing a callback function. This method allows for capturing errors within the main function and passing a second argument to assign a value if a property is not found.

example

result = getOptionalProperty(()=>test2.a.b.c.d);

code implementation

getOptionalProperty = <T, U>(callback: () => T | undefined, fallback?: U): T | U => {
    let result: T | undefined;

    try {
        result = callback();
    } catch (e) {
        result = undefined;
    }

    return (result === undefined) ? fallback : result;
}

Answer №2

I have implemented this function in my projects to serve a specific purpose

Object.resolve = function(path, obj, error) {
      var result = path.split('.').reduce(function(previous, current) {
          return previous ? previous[current] : undefined
      }, obj || self);
    var error = (typeof error == "undefined" ? undefined:error);
      if(!result) 
         return error;
      return result;
}

This function has three parameters: the path to access (e.g. a.b.c.d), the object itself, and the value to return if the property is not found. It traverses the object properties as per the given path and returns the default value if the property is not found.

Check out the examples below:

Object.resolve = function(path, obj, error) {
      var result = path.split('.').reduce(function(previous, current) {
          return previous ? previous[current] : undefined
      }, obj || self);
    var error = (typeof error == "undefined" ? undefined:error);
      if(!result) 
         return error;
      return result;
}


var test = { a: { b: { c: { d: 'e' } } } };

console.log(Object.resolve("a.b.c.d", test, "Not found"));
console.log(Object.resolve("a.b.d", test, "Not found"));

By the way, this function can be easily integrated into TypeScript code. I frequently utilize it in my Angular 5 projects.

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 best way to resize my hamburger menu and achieve a flawlessly circular border for it?

I've been struggling to reduce the size of my hamburger menu (both height and width) for some time now. I managed to make it a bit smaller, but I can't seem to figure out how to shrink it further. Additionally, I'm having trouble creating a ...

Transform the snake code by incorporating a visual image as the face of the serpent

Can someone help me change the snake's face to an image instead of a color fill in this code? And how can I add arrows for mobile compatibility? (function() { // Insert JS code here })(); // Insert CSS code here This code snippet includes functi ...

What is the method for retrieving array values from an attribute?

I am currently developing an Angular 6 application and I need to pass and retrieve array values dynamically through attributes. Here is the code snippet I have used for this purpose: HTML: <ul class="list-unstyled" id="list" [attr.parent_id]="123"> ...

Why does TypeScript struggle to accurately deduce the return type when provided with certain parameter values?

I have a function that uses a switch case to return different results depending on the input. The function, called "getTimeAgo," takes in two parameters: "date" (which can be either a Date object or a string) and "mode" (which can only be either "days" or ...

Using a Class Decorator in Typescript to Enhance Static Methods across all Classes

Imagine having a class filled with numerous static methods. The objective is to encapsulate each static method within a function. The specific aim is to handle async errors by applying .catch to every static method in the following manner: // Within user-r ...

Clicking to remove added child element

I have written a script that creates an image popup when the site loads. Here is the code: <script type="text/javascript"> function showPopup() { var div = document.createElement('div'); div.className += 'popup'; div.inne ...

Steps to display the Sidebar on top of the main information page

One unique feature of my website is the FiltersSideBar located on the left side of the page. It contains various filters to refine search results. To optimize user experience, I implemented a function that hides the sidebar at specific browser window size ...

Trouble with loading scripts after transitioning to a new page with AJAX (Barba.js)

Exploring the potential of using AJAX for smooth page transitions. Tried two different methods so far: manually coded transition from () and Barba.js approach (). With both methods, scripts work on initial load but fail to execute when navigating to anot ...

Making modifications to the state within a modal dialogue box

I am developing a note-taking application where users can write a title and note, and when they click submit, the note is displayed on the page. I want to implement an editing feature where clicking on the edit button opens a modal with the user's tit ...

Steps for combining two collections into a single output in MongoDB with Node.js

My MongoDB collections consist of data that I need to merge using the $lookup operation. However, the result I get contains a nested array structure that is not ideal. I am looking for a solution to format the result as shown below: First collection locati ...

Listeners for JavaScript actions

My typical approach to implementing a select box is as follows: <select size="1" name="example_length" onchange="callSomeMethod"> <option value="10" selected="selected"></option> <option value="25">25</option> < ...

Angular's window.onload event occurs when the page has finished

How can I achieve the equivalent of window.onload event in Angular? I am looking to fade out and remove my preloader, but only after all resources such as images are fully loaded. Using $viewContentLoaded alone does not cover this scenario since it indica ...

Is JavaScript the Key to Navigating Through a Website?

I am faced with the challenge of creating a script to extract a database from a website. The website's main page features a table where each row contains a link to another page that holds the desired database. Currently, my script can successfully e ...

What is the appropriate event type to pass to the onKeyPressed function in a React application utilizing MaterialUI and written with Typescript?

I am currently working on a React application using Typescript and MaterialUI, where I have implemented a TextField component. My goal is to capture the value of the input HTML element when the user presses the enter key. To achieve this, I have created ...

The error message indicates a compatibility issue between parameters 'r' and 'a'

Attempting to reproduce the code found in this blog post, but encountering some perplexing errors. import { option, identity, apply } from 'fp-ts'; import type { Kind, URIS } from 'fp-ts/HKT'; import { pipe } from 'fp-ts/lib/functi ...

Undefined global variable

Within my function, I have defined a global variable called window.playerLibrary. Interestingly, when I check the value of window.playerLibrary within the function itself (`var check #1`), it returns a value. However, if I try to check it just outside of t ...

Tips for using jQuery to identify the most recently modified row in an HTML table

Is there a way to identify the most recently modified (either newly added or changed) row in an HTML table? ...

Having trouble navigating typescript's "import" syntax in conjunction with compiler options like module and choosing between esnext and commonjs?

I am facing an issue with my typescript project that includes mocha tests. Here is a snippet of how the tests start: import { assert } from "chai"; import "@material/mwc-ripple"; //I need to test a script that uses this describe("simple test", () => { ...

Emulate a Click Using Pure JavaScript

I am looking to add a click event to my custom dropdown, which replaces a SELECT element. The purpose of this click event is to trigger the corresponding OPTION item when an LI element is clicked. It seems like Woocommerce uses some JavaScript or PHP func ...

Create a CSV file through an MVC Web API HttpResponse and retrieve it using AngularJS for downloading

I am attempting to create a CSV file from my web API and retrieve that file using angularjs. Below is an example of my API controller: [HttpPost] public HttpResponseMessage GenerateCSV(FieldParameters fieldParams) { var output = new byte[ ...