Docs Menu
Docs Home
/ /
Atlas Device SDKs
/ / /

Embedded Objects - React Native SDK

On this page

  • Create an Embedded Object
  • Example
  • Query a Collection on Embedded Object Properties
  • Example
  • Update an Embedded Object Property
  • Example
  • Overwrite an Embedded Object
  • Example
  • Delete an Embedded Object
  • Example

To create an embedded object, assign an instance of the embedded object to a parent object's property.

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 new Address embedded object and Contact parent object based on the TextInput values for the contact's name and address.

  • Adds an onPress event on the "Submit Contact" button that calls submitContact().

1const 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};

You can use dot notation to filter or sort a collection of objects based on an embedded object property value.

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 the useQuery 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.

1const 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};
1const 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};

To update a property in an embedded object, modify the property in a write transaction.

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 the useQuery 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 the street state variable.

  • Renders a TextInput that displays and changes the street state variable.

  • Adds an onPress event on the 'Update Street Address' button that calls updateStreet().

1// Find the contact you want to update
2const 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
2const 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};

To overwrite an embedded object, reassign the embedded object property of a party to a new instance in a write transaction.

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 the useQuery 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 new Address object that overwrites the existing address in the Contact 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 calls updateAddress().

1const 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};
1const 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};

Realm Uses Cascading Deletes for Embedded Objects. To delete an embedded object, delete the embedded object's parent.

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 the useQuery 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 the Contact object.

  • Add an onPress event on the "Delete Contact" button that calls deleteContact().

1const 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};
1type ContactInfoProps = {
2 contactCity: string;
3 postalCode: string;
4};
5
6const 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};

Back

UUID