setValue
Sets a value at a specific location in a JSON document using JSON Pointer notation. This function implements the JSON Pointer specification (RFC 6901) to navigate through nested object structures and set values at specific locations. JSON Pointer provides a standardized syntax for identifying specific locations within a JSON document using a sequence of reference tokens, enabling precise modification of nested data structures. The function supports both string and array representations of JSON Pointers:
- String format: Uses forward slashes (
/) as delimiters (e.g.,/foo/bar) - Array format: Each element represents a reference token (e.g., ["foo", "bar"])
- Empty pointer: Replaces the entire input object with the new value
- Root reference:
/or#/points to the root of the document Reference tokens are interpreted according to RFC 6901 escape sequences: ~0represents the literal character~~1represents the literal character/The function performs strict validation on the input object, requiring it to be either a plain object or an array. This ensures type safety and prevents unexpected behavior with primitive values or non-plain objects. Path Creation Behavior:- Creates intermediate objects/arrays automatically when they don't exist
- For numeric keys in objects, creates array structures when appropriate
- Preserves existing structure when possible
- Supports both object property and array index assignments Options: The function accepts an optional configuration object with the following properties:
overwrite(boolean, default:true): Controls behavior when the target location already has a value.true: Replaces existing values at the target locationfalse: Preserves existing values, only sets if location is undefinedpreserveNull(boolean, default:true): Controls behavior when encounteringnullvalues in intermediate paths.true: Preservesnullvalues, returns original object without modificationfalse: Replacesnullwith objects/arrays to continue path traversal Note: This only affects intermediate path segments, not the final target value. Setting a final value tonullis always allowed regardless of this option
Signature
const setValue: <Output extends Dictionary | Array<any> = Dictionary | Array<any>>(value: Dictionary | Array<any>, pointer: string | string[], input: any, options?: {
overwrite?: boolean;
preserveNull?: boolean;
}) => Output
Parameters
| Name | Type | Description |
|---|---|---|
value | - | The target JSON document to modify. Must be a plain object or array. Other types will throw an error. The input object is modified in place and returned. |
pointer | - | JSON Pointer specifying the location where the value should be set. Can be provided as: - String: JSON Pointer string following RFC 6901 format - Array: Sequence of reference tokens as string array |
input | - | The value to set at the specified location. Can be any valid JSON value (object, array, string, number, boolean, null). |
options | - | Optional configuration object controlling set behavior: - overwrite (boolean, default: true): Whether to replace existing values - preserveNull (boolean, default: true): Whether to preserve null in intermediate paths |
Returns
The modified input object with the value set at the specified location. The return value is the same reference as the input (modified in place).
Examples
Example 1
// Basic object property setting
const obj = {
foo: {
bar: "baz"
}
};
setValue(obj, '/foo/bar', 'qux');
// Returns: { foo: { bar: 'qux' } }
setValue(obj, ['foo', 'newProp'], 'value');
// Returns: { foo: { bar: 'qux', newProp: 'value' } }
Example 2
// Array manipulation
const data = {
users: [
{ name: "Alice", age: 30 }
]
};
setValue(data, '/users/0/age', 31);
// Returns: { users: [{ name: "Alice", age: 31 }] }
setValue(data, '/users/1', { name: "Bob", age: 25 });
// Returns: { users: [{ name: "Alice", age: 31 }, { name: "Bob", age: 25 }] }
Example 3
// Automatic path creation
const obj = {};
setValue(obj, '/nested/deep/property', 'value');
// Returns: { nested: { deep: { property: 'value' } } }
setValue(obj, '/array/0/item', 'first');
// Returns: {
// nested: { deep: { property: 'value' } },
// array: [{ item: 'first' }]
// }
Example 4
// Overwrite control
const obj = { existing: "original", other: "data" };
setValue(obj, '/existing', 'modified', { overwrite: true });
// Returns: { existing: "modified", other: "data" }
setValue(obj, '/existing', 'ignored', { overwrite: false });
// Returns: { existing: "modified", other: "data" } (unchanged)
setValue(obj, '/new', 'value', { overwrite: false });
// Returns: { existing: "modified", other: "data", new: "value" }
Example 5
// Null preservation in intermediate paths
const obj = { profile: null };
// Default behavior: null is preserved
setValue(obj, '/profile/name', 'John');
// Returns: { profile: null } (unchanged)
// Replace null: null is replaced with objects/arrays
const obj2 = { profile: null };
setValue(obj2, '/profile/name', 'John', { preserveNull: false });
// Returns: { profile: { name: "John" } }
// Setting final value to null is always allowed
const obj3 = { profile: { name: "John" } };
setValue(obj3, '/profile/name', null);
// Returns: { profile: { name: null } }
Example 6
// Escaped character handling
const obj = {};
setValue(obj, '/foo~1bar', 'slash'); // ~1 represents /
// Returns: { "foo/bar": "slash" }
setValue(obj, '/foo~0bar', 'tilde'); // ~0 represents ~
// Returns: { "foo/bar": "slash", "foo~bar": "tilde" }
Example 7
// Root replacement
const obj = { old: "data" };
setValue(obj, '', { completely: "new" });
// Returns: { completely: "new" }
Playground
// Basic object property setting const obj = { foo: { bar: "baz" } }; setValue(obj, '/foo/bar', 'qux'); // Returns: { foo: { bar: 'qux' } } setValue(obj, ['foo', 'newProp'], 'value'); // Returns: { foo: { bar: 'qux', newProp: 'value' } }