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 newAddressembedded object andContactparent object based on theTextInputvalues 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
Contactclass to theuseQueryhook.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
Contactclass to theuseQueryhook 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 thestreetstate variable.Renders a
TextInputthat displays and changes thestreetstate 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
Contactclass to theuseQueryhook 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 newAddressobject that overwrites the existing address in theContactobject.Renders
TextInputcomponents 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
Contactclass to theuseQueryhook.Filters for the
Contactobject 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 theContactobject.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 };