/only-data

Reduces objects and object graphs to just their data properties

Primary LanguageJavaScriptBSD 3-Clause "New" or "Revised" LicenseBSD-3-Clause

Only Data

Only Data will strip input down to just its data properties, removing "non-data" types such as functions and symbols. It works on primitive types, objects, arrays of objects, and nested graphs of objects.

Features:

  • Circular reference protection is provided by either throwing (the default), or removing them.
  • Ability to use a user-provided "reduction" function, allowing fine-grained control over the output.

Signature

onlyData(input[, options])

Parameters:
    input: Primitive | Object | Array<Any>
    options: Object | Array<String> | Function

Returns:
    Primitive | Object | Array<Any>

Usage

const { onlyData } = require("only-data");

const input = {
    name: "object",
    value: 42,
    invoke: function() { ... }
};

const data = onlyData(input);

// data: { name: "object", value: 42 }

Options

If options is a Array<String> then only properties matching these values will be included in the output.

If options is a Function then the function will be used as the reducer. See the Custom Reducer section.

If options is an object, it can contain the following settings...

Property Type Default Description
reducer Function | Array<String> A caller provided Reducer to use on object types. If set to an array of property names then only these properties will be included in the output. If a function is provided then it will be used to determine which properties are included. see the Custom Reducer section.
errorOnCircularReference Boolean true If true an error will be throw when a circular reference is encountered. If false then { } will be returned for any circular references
indicateCircularWarnings Boolean false If true, circular references will be replaced by { __circular: true }. If false then the behaviour falls back to the behaviour of the errorOnCircularReference option
disableCircularReferenceProtection Boolean false If you're sure that the input contains no circular references then setting this option to true will potentially increase performance. A stack overflow will occur if the input contains any circular references
circularReferences String Can be one of empty, error, indicate, or remove. Controls how circular references are handled. See Circular Reference Behaviour section.

Circular Reference Behaviour

By default, Only Data will throw an error whenever it encounters a circular reference. This will prevent costly stack overflows. You can control this behaviour using the circularReferences option.

circularReferences: "empty": Circular reference objects will be replaced with an empty object ({ })

const a = { name: "A" };
const b = { name: "B", val: a };
a.val = b; // This closes the loop and causes a circular reference

const data = onlyData(a, { circularReferences: "empty" });

// data: {
//   name: "A",
//   val: {
//     name: "B",
//     val: { }
//   }
// }

circularReferences: "error": An error will be thrown when a circular reference is detected. This is the default behaviour.

circularReferences: "indicate": Indicates circular references in the output by offending objects with { __circular: true }.

const a = { name: "A" };
const b = { name: "B", val: a };
a.val = b; // This closes the loop and causes a circular reference

const data = onlyData(a, { circularReferences: "remove" });

// data: {
//   name: "A",
//   val: {
//     name: "B",
//     val: { __circular: true }
//   }
// }

circularReferences: "remove": Removes circular reference objects from the graph altogether.

const a = { name: "A" };
const b = { name: "B", val: a };
a.val = b; // This closes the loop and causes a circular reference

const data = onlyData(a, { circularReferences: "remove" });

// data: {
//   name: "A",
//   val: {
//     name: "B",
//   }
// }

Custom Reducer

A custom reduction function has the signature (key: String, value: Any) -> Any. It will be called for each property of an object that needs to be reduced. Returning undefined from the custom reducer will cause the property to be ignored in the output.

function customReducer(key, value) {
    if (key === "propertyToIgnore")
        return;

    return value;
}

const data = onlyData(input, customReducer);