Skip to content

Instantly share code, notes, and snippets.

@TheNoim
Created September 30, 2018 07:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TheNoim/89a27eb7880e8a56e25246303e18fd7f to your computer and use it in GitHub Desktop.
Save TheNoim/89a27eb7880e8a56e25246303e18fd7f to your computer and use it in GitHub Desktop.
Fix realm infinity recursion and array stringify issue
const Dog = {
name: 'Dog',
properties: {
name: 'string',
owners: {type: 'linkingObjects', objectType: 'Person', property: 'dog'},
}
};
const Person = {
name: 'Person',
properties: {
name: 'string',
dog: 'Dog',
}
};
const schema = [Dog, Person];
const Realm = require("realm");
const fixRealm = require("./fixRealm");
const realm = new Realm({schema});
realm.write(() => {
realm.create('Person', {
name: "test",
dog: realm.create('Dog', {
name: 'harry'
})
});
});
const persons = realm.objects('Person');
console.log(JSON.stringify(fixRealm(persons, 2)));
// No infinity recursion and proper array in json
module.exports = (input = {}, depth = 5) => {
let result;
let realmThing
if (looksLikeArray(input)) {
result = [];
realmThing = input.slice(0, Infinity);
} else {
result = {};
realmThing = input;
}
return convert(realmThing, result, depth)
};
function convert(realmThing, target, maxDepth = 5, depth = 0) {
if (looksLikeArray(realmThing)) {
realmThing = realmThing.slice(0, Infinity);
}
for (const thingKey in realmThing) {
if (!realmThing.hasOwnProperty(thingKey)) continue;
let thing = realmThing[thingKey];
switch(typeof thing) {
case "boolean":
case "number":
target[thingKey] = thing;
break;
case "string":
target[thingKey] = thing === "" ? null : thing;
break;
case "object":
if (thing instanceof Date) {
target[thingKey] = thing;
} else if (thing instanceof ArrayBuffer) {
target[thingKey] = thing;
} else {
if (depth < maxDepth) {
if (looksLikeArray(thing)) {
target[thingKey] = convert(thing, [], maxDepth, depth + 1);
} else {
target[thingKey] = convert(thing, {}, maxDepth, depth + 1);
}
}
}
break;
}
}
return target;
}
function looksLikeArray(target = {}) {
if (target && target.slice && typeof target.slice === 'function') return true;
return false;
}
@TheNoim
Copy link
Author

TheNoim commented Sep 30, 2018

Warning!

This method is really slow and memory intensive on large objects/arrays.

ream-js should definitely implement a native method for this problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment