What is the correct way to convert a result from a realm query (RealmObject) to a javascript object using typescript? There are so many problems with using RealmObject that I believe it was not meant to be used, but I found no way to convert it except by forcing the object and pushing item by item into a new list.
It certainly is meant to be used. Not saying it's without any problems, but which have you experienced?
@bmunkholm
I recently had two problems. When I have an array in RealmObject and with a for I make a request in an enpoint item by item it does not go through the for, it is stopped in the first item. When I delete the item from a schema and then make a query of "select" I have an error that there are items removed. This last problem I found in issues here on github but without a solution #1769
Hmm, not sure I fully follow that description. Can you show it with code?
One of the huge advantages of having your objects stay in Realm instead of copying them out is consistency and change notifications, besides fast search of course. So understanding your real issue and need for copying out objects will help us guide you or improve the tool :-)
@bmunkholm
Thanks for helping. I did the gist with part of the code showing where I have difficulty, I'm new to realm. The generic.component.ts file would be a common react native component. Sorry, but I use Google Translator
GIST
First thing first: you don't need await in https://gist.github.com/viniciusvelasco/9cbaf70b0c874db0948dc252a5877828#file-event-service-ts-L25.
Converting a result set (Realm.Results) to plain JavaScript or TypeScript array is a bit tricky. The reason is that Realm.Results is not really an array but we try to emulate arrays as good as possible. For example:
Realm = require('realm');
schema = [{name: 'Cat', properties: { name: 'string'}}];
realm = new Realm({schema: schema});
realm.write(() => realm.create('Cat', {name: 'Garfield'}));
console.log(JSON.stringify(realm.objects('Cat')));
The output will be {"0":{"name":"Garfield"}}. If you need a plain JavaScript array, you can do:
let a = [];
for (let cat of realm.objects('Cat')) {
a.push(JSON.parse(JSON.stringify(cat)));
}
@kneth Thanks, I tried to do the conversion using JSON.parse and JSON.stringfy as your example but it didn't work, when it starts for of it gets stuck in the first position at the moment of doing JSON.stringfy and so it goes on and on. I solved inside for of by creating new instances of my objects and generating a new array, the bad thing is that there are many lines setting property to property
@viniciusvelasco It sounds like you have a cycle in your object graph (for example, an object refers to itself). In that case, you cannot use JSON.stringify() but must write your own conversion code.
Hello @kneth I am doing this manually, I will have to refactor to a lib is getting complex this conversion. I really like the realm and its performance but I have been displeased about it and debugging. But I understand the difficulty of debugging. Thanks a lot for the help.
What is the correct way to convert a result from a realm query (RealmObject) to a javascript object using typescript? There are so many problems with using RealmObject that I believe it was not meant to be used, but I found no way to convert it except by forcing the object and pushing item by item into a new list.
Array.from(query)?
Array.from(results) will still contain Realm.Objects. I can see the value that Realm JS provide the functionality.
I'm using Realm with Redux and Immutable.js together. Normally I convert all the JS objects into an immutable object before putting into Redux store by calling Immutable.fromJS(aJsObject).
But this doesn't work for realmObject so I have to do JSON.parse(JSON.stringnify(realmObject)) first. Which is a quite expensive operation.
So, do we have a better solution for this?
The stringify didn't work to me, and I'm using this function then I need to convert complex objects. It controls somehow circular references (not tested) but use carefully if object has large lists of children.
````
const convertToObject = (realmObject, maxDepth = 3, depth = 0) => {
depth++;
if (depth > maxDepth) {
return realmObject;
}
if (typeof realmObject !== 'object') {
return realmObject;
}
if (realmObject === null) {
return null;
}
let keys = Object.getOwnPropertyDescriptors(realmObject);
if (typeof realmObject.objectSchema === 'function') {
keys = realmObject.objectSchema().properties;
}
let object = {};
for (const key in keys) {
if (realmObject.hasOwnProperty(key)) {
//We don't follow linkinh objects
if (keys[key].type === 'linkingObjects') {
object[key] = realmObject[key];
} else if (isString(realmObject[key])) {
object[key] = realmObject[key];
} else if (isArrayLike(realmObject[key]) && !isString(realmObject[key])) {
object[key] = realmObject[key].map(item =>
convertToObject(item, maxDepth, depth, key),
);
} else {
object[key] = convertToObject(realmObject[key], maxDepth, depth, key);
}
}
}
return object;
};
````
for what works is:
convertToItem(item: MyObject & Realm.Object): MyObject {
var object = {};
var properties = Object.getOwnPropertyNames(MyObjectSchema.properties)
for (var property of properties) {
object[property] = item[property];
}
return object;
},
I'm using following line to convert JS object and Its working fine
JSON.parse(JSON.stringify(Array.prototype.slice.call(realmObjects, 0, realmObjects.length)));
Note: realm: 5.0.3
Why can't we just get a toObject() method? It' so trivial, keeps happening stuff like this using realm, trivial stuff we need to go search the issues, to "work arround".
It's a bit frustrating.
Is it something where a PR would be appreciated?
Some news on this?
Please take a look at https://github.com/realm/realm-js/pull/3044
Awesome, I guess this can be closed!
Most helpful comment
Why can't we just get a toObject() method? It' so trivial, keeps happening stuff like this using realm, trivial stuff we need to go search the issues, to "work arround".
It's a bit frustrating.
Is it something where a PR would be appreciated?