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

Mixed - React Native SDK

On this page

  • Realm Object Models
  • Create an Object With a Mixed Value
  • Query for Objects with a Mixed Value
  • Mixed Properties and Type Checking

Changed in version realm@12.9.0: Mixed properties can contain lists or dictionaries of mixed data.

New in version realm@10.5.0.

The Mixed data type is a realm property type that can hold any valid Realm data type except an embedded object or a set. You can create collections (lists, sets, and dictionaries) of type mixed. Properties using the mixed data type can also hold null values.

The Mixed type is indexable, but you can't use it as a primary key.

Properties using the Mixed type can hold null values and cannot be defined as optional. All instances of the JavaScript Number type in a Realm Mixed type are mapped to the Realm double type.

To set a property of your object model as Mixed, set the property's type to mixed.

class Cat extends Realm.Object {
static schema = {
name: 'Cat',
properties: {
name: 'string',
birthDate: 'mixed',
},
};
}
class Cat extends Realm.Object<Cat> {
name!: string;
birthDate?: Realm.Mixed;
static schema: ObjectSchema = {
name: 'Cat',
properties: {
name: 'string',
birthDate: 'mixed',
},
};
}

In JS SDK v12.9.0 and later, a mixed data type can hold collections (a list or dictionary, but not a set) of mixed elements. You can use mixed collections to model unstructured or variable data. For more information, refer to Define Unstructured Data.

  • You can nest mixed collections up to 100 levels.

  • You can query mixed collection properties and register a listener for changes, as you would a normal collection.

  • You can find and update individual mixed collection elements

  • You cannot store sets or embedded objects in mixed collections.

To use mixed collections, define the mixed type property in your data model. Then, create the list or dictionary collection.

Create an object with a Mixed value by using the new operator within a write transaction.

In the following CreateCatsInput example, we create several Cat realm objects with a Mixed type for the birthDate field.

The CreateCatsInput component does the following:

  • Get access to the opened realm instance by calling the useRealm() hook.

  • Use React's useEffect hook to call an anonymous function only once with useEffect and an empty dependency array.

  • Within the anonymous function, we create four different Cat objects by using the new operator to create a new realm object within a write transaction. Each of the Cat objects uses a different data type for the birthDate property.

  • Use the useQuery() hook to retrieve all Cat objects.

  • Map through the cats to render a list of Text components displaying each cat's name and birthDate.

1const CreateCatsInput = () => {
2 const realm = useRealm();
3
4 useEffect(() => {
5 // Add data to the Realm when the component mounts
6 realm.write(() => {
7 // create a Cat with a birthDate value of type string
8 realm.create('Cat', {
9 name: 'Euler',
10 birthDate: 'December 25th, 2017',
11 });
12
13 // create a Cat with a birthDate value of type date
14 realm.create('Cat', {
15 name: 'Blaise',
16 birthDate: new Date('August 17, 2020'),
17 });
18
19 // create a Cat with a birthDate value of type int
20 realm.create('Cat', {name: 'Euclid', birthDate: 10152021});
21
22 // create a Cat with a birthDate value of type null
23 realm.create('Cat', {name: 'Pythagoras', birthDate: null});
24 });
25 }, []);
26
27 // retrieve all cats
28 const cats = useQuery(Cat);
29
30 return (
31 <>
32 {cats.map(cat => (
33 <View>
34 <Text>{cat.name}</Text>
35 <Text>{String(cat.birthDate)}</Text>
36 </View>
37 ))}
38 </>
39 );
40};
1const CreateCatsInput = () => {
2 const realm = useRealm();
3
4 useEffect(() => {
5 // Add data to the Realm when the component mounts
6 realm.write(() => {
7 // create a Cat with a birthDate value of type string
8 realm.create('Cat', {
9 name: 'Euler',
10 birthDate: 'December 25th, 2017',
11 });
12
13 // create a Cat with a birthDate value of type date
14 realm.create('Cat', {
15 name: 'Blaise',
16 birthDate: new Date('August 17, 2020'),
17 });
18
19 // create a Cat with a birthDate value of type int
20 realm.create('Cat', {name: 'Euclid', birthDate: 10152021});
21
22 // create a Cat with a birthDate value of type null
23 realm.create('Cat', {name: 'Pythagoras', birthDate: null});
24 });
25 }, []);
26
27 // retrieve all cats
28 const cats = useQuery(Cat);
29
30 return (
31 <>
32 {cats.map(cat => (
33 <View>
34 <Text>{cat.name}</Text>
35 <Text>{String(cat.birthDate)}</Text>
36 </View>
37 ))}
38 </>
39 );
40};

To query for objects with a Mixed value, run the Collection.filtered() method and pass in a filter for a non-Mixed field. You can then print the value of the Mixed property or the entire object itself.

In the following CatInfoCard example, we query for a Cat object using the cat's name.

The CatInfoCard component does the following:

  • Get all Cat objects by passing the Cat class to the useQuery() hook, and then use filtered() to filter the results to receive only the cats whose names match the name passed as a prop. We then get the first matching cat and store it as a const variable.

  • Use dot notation to retrieve the Mixed property, birthDate.

  • Display the cat's name and birthdate in the render method if Realm finds the cat. If there is no cat that matches the name passed into the component as a prop, we render text that says "Cat not found".

1const CatInfoCard = ({catName}) => {
2 // To query for the cat's birthDate, filter for their name to retrieve the realm object.
3 // Use dot notation to access the birthDate property.
4 const cat = useQuery(
5 Cat,
6 cats => {
7 return cats.filtered(`name = '${catName}'`);
8 },
9 [catName],
10 )[0];
11 const catBirthDate = cat.birthDate;
12
13 if (cat) {
14 return (
15 <>
16 <Text>{catName}</Text>
17 <Text>{String(catBirthDate)}</Text>
18 </>
19 );
20 } else {
21 return <Text>Cat not found</Text>;
22 }
23};
1type CatInfoCardProps = {catName: string};
2
3const CatInfoCard = ({catName}: CatInfoCardProps) => {
4 // To query for the cat's birthDate, filter for their name to retrieve the realm object.
5 // Use dot notation to access the birthDate property.
6 const cat = useQuery(
7 Cat,
8 cats => {
9 return cats.filtered(`name = '${catName}'`);
10 },
11 [catName],
12 )[0];
13 const catBirthDate = cat.birthDate;
14
15 if (cat) {
16 return (
17 <>
18 <Text>{catName}</Text>
19 <Text>{String(catBirthDate)}</Text>
20 </>
21 );
22 } else {
23 return <Text>Cat not found</Text>;
24 }
25};

Because Mixed properties can be more than one type, you can't rely on the property's value being a specific type.

With Object.getPropertyType(), you can get a Mixed property's underlying type. This allows you build your own type checking.

// Use Type Predicates and Object.getPropertyType() to
// create a runtime type check for Mixed properties.
const isString = (
val: Mixed,
name: string,
object: Realm.Object,
): val is Realm.Types.String => {
return object.getPropertyType(name) === 'string';
};
type CatInfoCardProps = {catName: string};
const CatInfoCard = ({catName}: CatInfoCardProps) => {
const cat = useQuery(
Cat,
cats => {
return cats.filtered(`name = '${catName}'`);
},
[catName],
)[0];
// Use the type check to handle your data.
const catBirthDate = isString(cat.birthDate, 'birthDate', cat)
? cat.birthDate
: cat.birthDate.toString();
if (cat) {
return (
<>
<Text>{catName}</Text>
<Text>{catBirthDate}</Text>
</>
);
} else {
return <Text>Cat not found</Text>;
}
};

Back

Sets