Easily retrieve the value of a nested property inside an object in javascript without the need for optional chaining in 2023.
Tags: javascript
Published: 2023-08-10 12:35:59

---
title: Easily retrieve the value of a nested property inside an object in javascript without the need for optional chaining in 2023.
published: true
tags: Javascript
canonical_url: https://blog.melvinvmegen.com/snippets/object-nested-value
---

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9uia0b99db9lhd2f7dhs.png)

## Implementation

```js
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;
}
```

## 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 ?.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/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()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/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:

```js
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
```

**Note:** [Optional chaining](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/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.

```js
// 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
```

## 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.