Working on React Native Realm database ("realm": "11.0.0"), I can’t make Embedded Objects documented here work.
The error I have is :
ERROR Exception in HostFunction: Embedded objects cannot be created directly.
Please find below the code you can copy/past to reproduce the problem if you like. If you uncomment "embedded: true", this one-to-many relationship example works.
import React from "react";
import { View, Text } from "react-native";
import Realm from "realm";
export class Project extends Realm.Object<Project> {
public _id: number;
public name: string;
public tasks: Realm.List<Task>;
static schema = {
name: "Project",
primaryKey: "_id",
properties: {
_id: "int",
name: "string",
tasks: { type: "list", objectType: "Task" },
},
};
}
export class Task extends Realm.Object<Task> {
public description: string;
static schema = {
name: "Task",
embedded: true, // uncomment
properties: {
description: "string",
},
};
}
(async () => {
let realm: any;
try {
realm = await Realm.open({
inMemory: true,
schema: [Project, Task],
});
} catch (e) {
console.error(e.message);
}
try {
realm.write(() => {
const t1 = realm.create(Task, {
description: "T1",
});
const t2 = realm.create(Task, {
description: "T2",
});
realm.create(Project, {
_id: 1,
name: "P1",
tasks: [t1, t2],
});
});
} catch (e) {
console.error(e.message);
}
console.log(JSON.stringify(realm.objects(Project), null, 3));
realm.close();
})();
export const App = () => {
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text style={{ fontSize: 25 }}>Please look at the console</Text>
</View>
);
};
2
Answers
Thanks to Jay answer and after reading the doc more carefully, I changed the creation of Project and its embedded Tasks like this and it works :
But I am still unable to create embedded object when I model objects with class and constructor or class and static generate(). If you have a working example of this kind, please post it.
UPDATE (25/03/2023) : To be more explicit, how to modify the code below to make the embedded feature work ? But if possible, TASK being a class with a constructor.
Without the "embedded: true," line, the output of this code is:
With the "embedded: true," the output of this code is:
There’s an important differentiation between a Realm Object and a Realm Embedded object:
A Realm object is a separate, independent object that is directly managed by Realm.
Whereas an Embedded Object is just that; embedded within a parent object. It is not a separate, independent object and is only managed by Realm through its parent object. Because of that, Embedded Objects cannot be directly written to Realm.
An embedded object does not exist without it’s parent object. It cannot be stored in Realm directly; it has to be added to it’s parent and then the parent must be stored (or it could be added to an already existing parent object).
Big picture is that Embedded Objects are actually part of the parent’s schema and when the parent is deleted, so are it’s embedded objects.
Additionally, Embedded Objects can only be queried through the parent object; so for example, suppose a Person object has an embedded Dog object. If you wanted to look for a person who has a dog named spot, it would be (pseudo code)
note that
so this
won’t work as a
Task
is part of theProject
‘s schemaEDIT
An example would be a business that has several addresses. The address themselves don’t need to be separatly managed objects as they are directly tied to the parent business.
Here’s a business object which will contain several embedded address objects
and then the embedded address objects look like this
note that embedded objects must be set to
embedded: true
and then also insure the embedded object does not have a primary key.