Skip to content

Instantly share code, notes, and snippets.

@arabold
Last active April 13, 2020 14:26
Show Gist options
  • Save arabold/ca63ae24b4fb21cb8213eb2e49906fe6 to your computer and use it in GitHub Desktop.
Save arabold/ca63ae24b4fb21cb8213eb2e49906fe6 to your computer and use it in GitHub Desktop.
/**
* Destroys circular references for use with JSON serialization
*
* @param from - Source object or array
* @param seen - Array with object already serialized. Set to `[]` (empty array)
* when using this function!
*/
private static _destroyCircular(from: any, seen: any[]) {
let to: any;
if (Array.isArray(from)) {
to = [];
} else {
to = {};
}
seen.push(from);
Object.keys(from).forEach((key) => {
const value = from[key];
if (typeof value === "function") {
// No Logging of functions
return;
}
if (typeof value === "symbol") {
// Use the symbol's name
to[key] = value.toString();
return;
}
if (!value || typeof value !== "object") {
// Simple data types
to[key] = value;
return;
}
if (typeof value === "object" && typeof value.toJSON === "function") {
to[key] = value.toJSON();
return;
}
if (!seen.includes(from[key])) {
to[key] = Logger._destroyCircular(from[key], seen.slice(0));
return;
}
to[key] = "[Circular]";
});
if (typeof from.name === "string") {
to.name = from.name;
}
if (typeof from.message === "string") {
to.message = from.message;
}
if (typeof from.stack === "string") {
to.stack = from.stack;
}
return to;
}
/**
* Helper function to serialize class instances to plain objects for logging
*
* @param key - Property key
* @param value - Property value
*
* @example
* const myObj = { foo: "bar" };
* const str = JSON.stringify(myObj, serializeObj, "\t");
*/
private static _serializeObj(key: any, value: any): any {
if (typeof value === "object" && value !== null) {
return Logger._destroyCircular(value, []);
}
return value;
}
/**
* Like `JSON.stringify` but handles circular references and serializes error objects.
*/
static stringify(value: any, space?: string | number | undefined): string {
return JSON.stringify(value, Logger._serializeObj, space);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment