Created
September 30, 2018 07:29
-
-
Save TheNoim/89a27eb7880e8a56e25246303e18fd7f to your computer and use it in GitHub Desktop.
Fix realm infinity recursion and array stringify issue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Warning!
This method is really slow and memory intensive on large objects/arrays.
ream-js should definitely implement a native method for this problem.