DEV Community

Melvinvmegen
Melvinvmegen

Posted on • Originally published at blog.melvinvmegen.com

Easily retrieve the value of a nested property inside an object in javascript without the need for optional chaining in 2023.

Image description

Implementation

function getObjectValue(obj, path, defaultValue = undefined) {
  const traverse = (regexp) => {
    return String.prototype.split
      .call(path, regexp)
      .filter(Boolean)
      .reduce(
        (res, key) => (res !== null && res !== undefined 
          ? res[key] 
          : res
        ),
        obj
      );
  };
  const result = traverse(/[,[\]]+?/) || traverse(/[,[\].]+?/);
  return result === undefined || result === obj 
   ? defaultValue 
   : result;
}
Enter fullscreen mode Exit fullscreen mode

Context

When working with complex JavaScript objects, it's often necessary to access values at specific paths within the object. However, this can be challenging when the object is deeply nested, and the path is complicated altought nowadays we could alternatively use the optional chaining ?. for a less elegant aproach (by the way it's not always supported like in Vue 2 template block). The getObjectValue() function defined in this code offers a convenient way to retrieve values at any given path in the object.

Usage

The getObjectValue() function takes three arguments: the object to dig into, the path to the desired value, and an optional default value to return if the path does not correspond to any value.

Inside the getObjectValue() function we define yet another function traverse(), which uses regular expressions to split the path string into individual keys. These keys are then traversed using the reduce() method until the desired value is reached. If the value is found, it is returned, otherwise, the default value is returned.

Now, suppose you're building a weather application that consumes an API that returns an object with weather information for a given location. The object contains nested structures for various attributes, such as temperature, humidity, and precipitation.

To display the weather information on your application's user interface, you'll need to extract specific values from the API response object if for example, you want to display the current temperature in Celsius, the precipitation probability, and the wind speed in miles per hour you can easily extract these values from the API response object using the getObjectValue(), no matter how deeply they are nested:

const response = {
  locations: [
    {
      name: "London",
      country: "United Kingdom",
      region: "City of London, Greater London",
      lat: "51.517",
      lon: "-0.106",
      timezone_id: "Europe/London",
      localtime: "2023-04-08 12:30",
      current: {
        temperature: 15,
        humidity: 75,
        precipitation: {
          probability: 40,
          type: "rain",
        },
        wind_speed: {
          mph: 10,
          kph: 16,
        },
      },
    },
  ],
};

getObjectValue(response, "locations[0].current.temperature"); // 15
getObjectValue(response, "locations[0].current.precipitation.probability"); // 40
getObjectValue(response, "locations[0].current.wind_speed.mph"); // 10
Enter fullscreen mode Exit fullscreen mode

Note: Optional chaining is a relatively new JavaScript feature that allows you to access nested properties of an object without throwing an error if any of the intermediate properties are null or undefined (as long as each property that could potentially be falsy is precedeted with a ?.). This is to me a more concise but less readable alternative than the getObjectValue() function.

// Alternative usage: optional chaining
response?.locations?.[0]?.current?.temperature; // 15
response?.locations?.[0]?.current?.precipitation?.probability; // 40
response?.locations?.[0]?.current?.wind_speed?.mph; // 10
Enter fullscreen mode Exit fullscreen mode

Conclusion:

The getObjectValue() function provides a convenient and flexible way to retrieve values at specific paths within a JavaScript object. By using regular expressions to split the path string into individual keys and iteratively traversing the object, this function can handle even the most complex nested structures.

Top comments (0)