본문으로 건너뛰기

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:
  • ~0 represents the literal character ~
  • ~1 represents 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 location
  • false: Preserves existing values, only sets if location is undefined
  • preserveNull (boolean, default: true): Controls behavior when encountering null values in intermediate paths.
  • true: Preserves null values, returns original object without modification
  • false: Replaces null with objects/arrays to continue path traversal Note: This only affects intermediate path segments, not the final target value. Setting a final value to null is 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​

NameTypeDescription
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' } }