Embedded Objects - React Native SDK
On this page
Create an Embedded Object
To create an embedded object, assign an instance of the embedded object to a parent object's property.
Example
In the following CreateContact
example, we create a new Contact
object
with an embedded Address
object.
The CreateContact
component does the following:
Creates React state variables that represent the contact's name and address details.
Gets access to an open realm instance by calling the
useRealm()
hook within the component.Creates a component method
submitContact()
that performs a write transaction to create a newAddress
embedded object andContact
parent object based on theTextInput
values for the contact's name and address.Adds an onPress event on the "Submit Contact" button that calls
submitContact()
.
1 const CreateContact = () => { 2 const [name, setContactName] = useState(''); 3 const [street, setStreet] = useState(''); 4 const [city, setCity] = useState(''); 5 const [country, setCountry] = useState(''); 6 const [postalCode, setPostalCode] = useState(''); 7 const realm = useRealm(); 8 9 const submitContact = () => { 10 // Create a Contact within a write transaction 11 realm.write(() => { 12 // Create an embedded Address object 13 const address = { 14 street, 15 city, 16 country, 17 postalCode, 18 }; 19 20 realm.create('Contact', { 21 _id: new Realm.BSON.ObjectID(), 22 name, 23 // Embed the address in the Contact object 24 address, 25 }); 26 }); 27 }; 28 return ( 29 <View> 30 <TextInput value={name} onChangeText={text => setContactName(text)} /> 31 <TextInput value={street} onChangeText={text => setStreet(text)} /> 32 <TextInput value={city} onChangeText={text => setCity(text)} /> 33 <TextInput value={country} onChangeText={text => setCountry(text)} /> 34 <TextInput 35 value={postalCode} 36 onChangeText={text => setPostalCode(text)} 37 /> 38 <Button 39 title='Submit Contact' 40 onPress={submitContact} 41 /> 42 </View> 43 ); 44 };
Query a Collection on Embedded Object Properties
You can use dot notation to filter or sort a collection of objects based on an embedded object property value.
Example
In the following ContactList
example, we filter and query an embedded
Address
object.
The ContactList
component does the following:
Performs a query for all contacts by passing the
Contact
class to theuseQuery
hook.Filters for contacts with the name "John Smith" by passing collection.filtered() on the query
"name == 'John Smith'"
.Retrieves the contact's street address by using dot notation.
1 const ContactList = ({postalCode}) => { 2 // Run the `.filtered()` method on all the returned Contacts to get 3 // contacts with a specific postal code. 4 const contactsInArea = useQuery( 5 Contact, 6 contacts => { 7 return contacts.filtered(`address.postalCode == '${postalCode}'`); 8 }, 9 [postalCode], 10 ); 11 12 if (contactsInArea.length) { 13 return ( 14 <> 15 <FlatList 16 testID='contactsList' 17 data={contactsInArea} 18 renderItem={({item}) => { 19 <Text>{item.name}</Text>; 20 }} 21 /> 22 </> 23 ); 24 } else { 25 return <Text>No contacts found in this area.</Text>; 26 } 27 };
1 const ContactList = ({postalCode}: {postalCode: string}) => { 2 // Run the `.filtered()` method on all Contact objects to get 3 // contacts with a specific postal code. 4 const contactsInArea = useQuery(Contact, contacts => { 5 return contacts.filtered(`address.postalCode == '${postalCode}'`); 6 }); 7 8 if (contactsInArea.length) { 9 return ( 10 <> 11 <FlatList 12 data={contactsInArea} 13 renderItem={({item}) => { 14 <Text>{item.name}</Text>; 15 }} 16 /> 17 </> 18 ); 19 } else { 20 return <Text>No contacts found in this area.</Text>; 21 } 22 };
Update an Embedded Object Property
To update a property in an embedded object, modify the property in a write transaction.
Example
In the following UpdateContact
example, we update the street
property for
an embedded Address
object.
The UpdateContact
component does the following:
Creates a React state variable that represents the contact's new street address.
Performs a query for all contacts by passing the
Contact
class to theuseQuery
hook and filters for the contact that matches the name passed into the component as a prop.Gets access to an opened realm instance by calling the
useRealm()
hook within the component.Creates a component method
updateStreet()
that performs a write transaction and sets the contact's street address to the value of thestreet
state variable.Renders a
TextInput
that displays and changes thestreet
state variable.Adds an onPress event on the
'Update Street Address'
button that callsupdateStreet()
.
1 // Find the contact you want to update 2 const UpdateContact = ({contactId}) => { 3 const [street, setStreet] = useState(''); 4 const contact = useObject(Contact, contactId); 5 const realm = useRealm(); 6 7 const updateStreet = () => { 8 // Modify the property of the embedded Address object in a write transaction 9 realm.write(() => { 10 // Update the address directly through the contact 11 contact.address.street = street; 12 }); 13 }; 14 15 return ( 16 <View> 17 <Text>{contact.name}</Text> 18 <TextInput 19 value={street} 20 onChangeText={setStreet} 21 placeholder='Enter New Street Address' 22 /> 23 <Button 24 onPress={updateStreet} 25 title='Update Street Address' 26 /> 27 </View> 28 ); 29 };
1 // Find the contact you want to update 2 const UpdateContact = ({contactId}: {contactId: Realm.BSON.ObjectId}) => { 3 const [street, setStreet] = useState(''); 4 const contact = useObject(Contact, contactId); 5 const realm = useRealm(); 6 7 const updateStreet = () => { 8 // Modify the property of the embedded Address object in a write transaction 9 realm.write(() => { 10 // Update the address directly through the contact 11 contact!.address.street = street; 12 }); 13 }; 14 15 return ( 16 <View> 17 <Text>{contact!.name}</Text> 18 <TextInput 19 value={street} 20 onChangeText={setStreet} 21 placeholder='Enter New Street Address' 22 /> 23 <Button 24 onPress={updateStreet} 25 title='Update Street Address' 26 /> 27 </View> 28 ); 29 };
Overwrite an Embedded Object
To overwrite an embedded object, reassign the embedded object property of a party to a new instance in a write transaction.
Example
In the following OverwriteContact
example, we overwrite an embedded Address
object.
The OverwriteContact
component does the following:
Creates React state variables that represent the contact's new address.
Performs a query for all contacts by passing the
Contact
class to theuseQuery
hook and filters for the contact that matches the name passed into the component as a prop.Gets access to an opened realm instance by calling the
useRealm()
hook within the component.Creates a component method
updateAddress()
that performs a write transaction and creates a newAddress
object that overwrites the existing address in theContact
object.Renders
TextInput
components that display and change the state variables for the new address.Adds an onPress event on the
'Overwrite Address'
button that callsupdateAddress()
.
1 const OverwriteContact = ({contactId}) => { 2 const [street, setStreet] = useState(''); 3 const [city, setCity] = useState(''); 4 const [country, setCountry] = useState(''); 5 const [postalCode, setPostalCode] = useState(''); 6 const contact = useObject(Contact, contactId); 7 const realm = useRealm(); 8 9 const updateAddress = () => { 10 realm.write(() => { 11 // Within a write transaction, overwrite the embedded object with the new address 12 const address = { 13 street, 14 city, 15 country, 16 postalCode, 17 }; 18 19 contact.address = address; 20 }); 21 }; 22 return ( 23 <View> 24 <Text>{contact.name}</Text> 25 <Text>Enter the new address:</Text> 26 <TextInput 27 value={street} 28 onChangeText={setStreet} 29 placeholder='Street' 30 /> 31 <TextInput value={city} onChangeText={setCity} placeholder='City' /> 32 <TextInput 33 value={country} 34 onChangeText={setCountry} 35 placeholder='Country' 36 /> 37 <TextInput 38 value={postalCode} 39 onChangeText={setPostalCode} 40 placeholder='Postal Code' 41 /> 42 <Button 43 onPress={updateAddress} 44 title='Overwrite Address' 45 /> 46 </View> 47 ); 48 };
1 const OverwriteContact = ({ 2 contactId, 3 }: { 4 contactId: Realm.BSON.ObjectId; 5 }) => { 6 const [street, setStreet] = useState(''); 7 const [city, setCity] = useState(''); 8 const [country, setCountry] = useState(''); 9 const [postalCode, setPostalCode] = useState(''); 10 const contact = useObject(Contact, contactId); 11 const realm = useRealm(); 12 13 const updateAddress = () => { 14 realm.write(() => { 15 // Within a write transaction, overwrite the embedded object with the new address 16 const address = { 17 street, 18 city, 19 country, 20 postalCode, 21 }; 22 23 contact!.address = address; 24 }); 25 }; 26 27 return ( 28 <View> 29 <Text>{contact!.name}</Text> 30 <Text>Enter the new address:</Text> 31 <TextInput 32 value={street} 33 onChangeText={setStreet} 34 placeholder='Street' 35 /> 36 <TextInput value={city} onChangeText={setCity} placeholder='City' /> 37 <TextInput 38 value={country} 39 onChangeText={setCountry} 40 placeholder='Country' 41 /> 42 <TextInput 43 value={postalCode} 44 onChangeText={setPostalCode} 45 placeholder='Postal Code' 46 /> 47 <Button 48 onPress={updateAddress} 49 title='Overwrite Address' 50 /> 51 </View> 52 ); 53 };
Delete an Embedded Object
Realm Uses Cascading Deletes for Embedded Objects. To delete an embedded object, delete the embedded object's parent.
Example
In the following DeleteContact
example, we delete an embedded object and its
parent object.
The DeleteContact
component does the following:
Performs a query for all contacts by passing the
Contact
class to theuseQuery
hook.Filters for the
Contact
object that matches the name passed into the component as a prop.Gets access to an open realm instance by calling the
useRealm()
hook within the component.Creates a component method
deleteContact()
that performs a write transaction and calls Realm.delete() to remove theContact
object.Add an onPress event on the "Delete Contact" button that calls
deleteContact()
.
1 const ContactInfo = ({contactCity, postalCode}) => { 2 const realm = useRealm(); 3 const parentsToDelete = useQuery( 4 Contact, 5 contacts => { 6 return contacts.filtered(`address.city == '${contactCity}'`); 7 }, 8 [contactCity], 9 ); 10 const embeddedToDelete = useQuery( 11 Contact, 12 contacts => { 13 return contacts.filtered(`address.postalCode == '${postalCode}'`); 14 }, 15 [postalCode], 16 ); 17 18 const deleteParentObject = () => { 19 realm.write(() => { 20 // Delete all objects that match the filter. 21 // Also deletes embedded objects. 22 realm.delete(parentsToDelete); 23 }); 24 }; 25 26 const deleteEmbeddedObject = () => { 27 realm.write(() => { 28 embeddedToDelete.forEach(contact => { 29 // Delete just the embedded object. 30 realm.delete(contact.address); 31 }); 32 }); 33 }; 34 35 return ( 36 <View> 37 <Text testID='contactCityText'>{contactCity}</Text> 38 <Button 39 onPress={deleteParentObject} 40 title='Delete Contact' 41 /> 42 <Button 43 onPress={deleteEmbeddedObject} 44 title='Delete Address' 45 /> 46 </View> 47 ); 48 };
1 type ContactInfoProps = { 2 contactCity: string; 3 postalCode: string; 4 }; 5 6 const ContactInfo = ({contactCity, postalCode}: ContactInfoProps) => { 7 const parentsToDelete = useQuery(Contact, contacts => { 8 return contacts.filtered(`address.city == '${contactCity}'`); 9 }); 10 const embeddedToDelete = useQuery(Contact, contacts => { 11 return contacts.filtered(`address.postalCode == '${postalCode}'`); 12 }); 13 const realm = useRealm(); 14 15 const deleteParentObject = () => { 16 realm.write(() => { 17 // Delete all objects that match the filter. 18 // Also deletes embedded objects. 19 realm.delete(parentsToDelete); 20 }); 21 }; 22 23 const deleteEmbeddedObject = () => { 24 realm.write(() => { 25 embeddedToDelete.forEach(contact => { 26 // Delete just the embedded object. 27 realm.delete(contact.address); 28 }); 29 }); 30 }; 31 32 return ( 33 <View> 34 <Text testID='contactCityText'>{contactCity}</Text> 35 <Button 36 onPress={deleteParentObject} 37 title='Delete Contact' 38 /> 39 <Button 40 onPress={deleteEmbeddedObject} 41 title='Delete Address' 42 /> 43 </View> 44 ); 45 };