Safely get a dot-notated property within an object with optional default values.
npx @tessl/cli install tessl/npm-dlv@1.1.0dlv is a minimal utility library (only 130 bytes) that provides safe access to deeply nested object properties using dot notation or array paths. It prevents runtime errors when accessing non-existent nested properties and supports default values when the full key path is missing or undefined.
npm install dlvES Modules:
import dlv from 'dlv';CommonJS:
const dlv = require('dlv');UMD/Browser:
<script src="path/to/dlv.umd.js"></script>
<!-- Available as global 'dlv' -->import dlv from 'dlv';
const obj = {
a: {
b: {
c: 1,
d: undefined,
e: null
}
}
};
// Use string dot notation for keys
const value1 = dlv(obj, 'a.b.c'); // Returns: 1
// Or use an array of keys
const value2 = dlv(obj, ['a', 'b', 'c']); // Returns: 1
// Returns undefined if the full key path does not exist
const value3 = dlv(obj, 'a.b.f'); // Returns: undefined
// Optional default value when path is missing or undefined
const value4 = dlv(obj, 'a.b.f', 'default'); // Returns: 'default'
const value5 = dlv(obj, 'a.b.d', 'default'); // Returns: 'default' (d is undefined)
// Falsy values are preserved if they exist at the target path
const value6 = dlv(obj, 'a.b.e', 'default'); // Returns: null (not 'default')
// Handles undefined objects gracefully
const value7 = dlv(undefined, 'a.b.c'); // Returns: undefined
const value8 = dlv(undefined, 'a.b.c', 'default'); // Returns: 'default'Safely retrieves a dot-notated property from within an object without throwing errors for non-existent paths.
/**
* Safely get a dot-notated property within an object
* @param {any} obj - The object to traverse
* @param {string|Array} key - Dot-notated path string (e.g., 'a.b.c') or array of keys (e.g., ['a', 'b', 'c'])
* @param {any} [def] - Default value to return if the full key path doesn't exist or resolves to undefined
* @returns {any} The value at the specified path, or the default value, or undefined
*/
function dlv(obj, key, def);Parameter Details:
obj (any): The object to traverse. Can be any value including null, undefined, or non-objectskey (string|Array):
def (any, optional): Default value returned when:
Return Value:
def) if the path doesn't exist, resolves to undefined, or the object is null/undefinedundefined if no default is provided and the path doesn't exist or resolves to undefinedKey Behaviors:
Usage Examples:
import dlv from 'dlv';
// Complex nested object
const user = {
profile: {
personal: {
name: 'Alice',
age: 0,
active: false
},
settings: {
theme: null,
notifications: undefined
}
}
};
// Basic access
dlv(user, 'profile.personal.name'); // 'Alice'
dlv(user, ['profile', 'personal', 'name']); // 'Alice'
// Missing path
dlv(user, 'profile.work.title'); // undefined
dlv(user, 'profile.work.title', 'Unknown'); // 'Unknown'
// Falsy value preservation
dlv(user, 'profile.personal.age'); // 0 (not undefined)
dlv(user, 'profile.personal.active'); // false (not undefined)
dlv(user, 'profile.settings.theme'); // null (not undefined)
// Undefined handling
dlv(user, 'profile.settings.notifications'); // undefined
dlv(user, 'profile.settings.notifications', 'disabled'); // 'disabled'
// Edge cases
dlv(null, 'any.path'); // undefined
dlv(null, 'any.path', 'default'); // 'default'
dlv(user, '', 'default'); // 'default' (empty path)
// API responses
const apiResponse = {
data: {
users: [
{ id: 1, meta: { created: '2023-01-01' } },
{ id: 2 } // missing meta
]
}
};
const firstUserCreated = dlv(apiResponse, 'data.users.0.meta.created', 'N/A');
const secondUserCreated = dlv(apiResponse, 'data.users.1.meta.created', 'N/A');
// firstUserCreated: '2023-01-01'
// secondUserCreated: 'N/A'Error Handling:
key parameter is undefined (no path provided)Since dlv is written in vanilla JavaScript, it doesn't include built-in TypeScript types, but the function signature would be:
/**
* TypeScript type definitions for dlv (not included in package)
*/
declare function dlv<T = any>(
obj: any,
key: string | (string | number)[],
def?: T
): T | undefined;
export default dlv;