Technical Interview Challenge: The "Safe-Path" Configuration Resolver
Context
In large-scale microfrontend architectures or complex CMS template engines, applications often consume deeply nested JSON configurations. A common runtime failure occurs when code attempts to access a property on an undefined or null intermediate key (the classic Cannot read property 'x' of undefined).
While modern JavaScript offers Optional Chaining (?.), many template engines and legacy utility libraries require a robust, string-based path resolver that can handle dynamic paths and provide fallback defaults to ensure the UI never crashes due to a malformed configuration.
Problem Statement
Implement a utility function get(obj, path, defaultValue) that retrieves a value from an object at a specified nested path. If the resolved value is undefined or if the path is unreachable, return the defaultValue.
Requirements:
Path Parsing: The
pathcan be a string using dot notation (a.b.c) or bracket notation for arrays (a[0].b).Null Safety: The function must handle
nullorundefinedinput objects gracefully without throwing an error.Defaulting: If any segment of the path does not exist, the function should immediately bail and return the provided
defaultValue.Complex Keys: Assume the object may contain both nested objects and arrays.
Example Use Cases
Example 1: Standard Deep Access
JavaScript
const config = { settings: { theme: { color: "blue" } } };
get(config, "settings.theme.color", "red");
// Expected Output: "blue"Example 2: Array Indexing
JavaScript
const data = { users: [{ id: 1, name: "Alice" }, { id: 2, name: "Bob" }] };
get(data, "users[1].name", "Unknown");
// Expected Output: "Bob"Example 3: Missing Path with Default
JavaScript
const user = { profile: { email: "rahul@google.com" } };
get(user, "profile.phone.mobile", "No Phone Provided");
// Expected Output: "No Phone Provided"Example 4: Handling Null Root
JavaScript
get(null, "any.path", 0);
// Expected Output: 0Interview Evaluation Criteria
Regex/Parsing Strategy: How do you normalize the path string? (e.g., converting
a[0].binto a consistent array of keys like['a', '0', 'b']).Iterative vs. Recursive: Can you implement this without causing a stack overflow on extremely deep objects?
Falsy Value Handling: Does your function correctly return
falseor0if those are the actual values at the path, or does it accidentally return thedefaultValue?Performance: Are you re-parsing the string on every step, or splitting it once at the start?