Explain Codes LogoExplain Codes Logo

Convert a JavaScript string in dot notation into an object reference

javascript
object-manipulation
lodash
error-management
Anton ShumikhinbyAnton Shumikhin·Aug 19, 2024
TLDR
const resolvePath = (object, path) => path.split('.').reduce((o, k) => (o || {})[k], object); // Example usage: const data = { a: { b: { c: 2 } } }; const value = resolvePath(data, 'a.b.c'); // Returns 2, not a surprise!

This one-liner uses the reduce function to iteratively access deeply nested properties. Convert the dot-separated string into keys, and if the path is not found, don't panic, it safely returns undefined.

Facing challenges with object manipulation

Object manipulation in JavaScript can get tricky when it involves serialized data, user-displayed data, or deeply nested properties. Here, it gets important to create an efficient and safe solution per your unique use case.

Beyond getting, updating properties

Our fast answer is essentially using a getter function. But what if you want to update (or set) these properties as well? No worries, JavaScript has your back:

const setPath = (object, path, value) => { const keys = path.split('.'); keys.reduce((o, k, i) => (o[k] = keys.length === i + 1 ? value : o[k] || {}), object); }; // Let's give 'a.b.c' a promotion setPath(data, 'a.b.c', 3); // Now 'a.b.c' is 3, what a glow-up!

This function transforms our keys, digs into the object, and assigns our new value when it reaches the final property.

The recursive traversal solution

When iteratively seems too mainstream, we embrace recursion:

function resolvePathRecursively(object, path) { let keys = path.split('.'); let current = object; for (let key of keys) { if (current[key] === undefined) return undefined; current = current[key]; } return current; }

This function strips the string path into keys and delves deeper into the object layer by layer.

Leveraging Lodash for safe & breezy object manipulation

Lodash steps in when JavaScript syntax seems verbose and confusing.

// Assuming Lodash is included in your project const value = _.get(data, 'a.b.c');

Just use Lodash's _.get method in one line and access your nested properties like a walk in the park! Don't worry about adding the whole library - lodash.get is available as a standalone package using npm.

Save my code from the eval monster

When trying to convert string paths to object references, using eval might seem tempting but beware, it's like making a deal with a monster! 🐲 It can introduce severe security vulnerabilities, especially if you are dealing with user-generated content. Stick to the safer methods we have explored.

Handling the unexpected: Error management and defaults

Practical applications often require handling instances where a path could lead to undefined. Using default values is an approach that dodges the bullet:

const resolvePathWithDefault = (object, path, defaultValue = undefined) => path.split('.').reduce((o, k) => (o || {})[k], object) || defaultValue;

Making friends with Object.assign

While traversing your object painting, you might want to add more layers.

const mergeProperties = (target, path, value) => { let lastKeyIndex = path.lastIndexOf('.'); let lastKey = path.substring(lastKeyIndex + 1); let lastObject = resolvePath(target, path.substring(0, lastKeyIndex)); Object.assign(lastObject, { [lastKey]: value }); };

The Object.assign method ensures new properties merge safely into the existing object, enhancing the sturdiness of your artwork.