Mixed - React Native SDK
On this page
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.
Realm Object Models
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', }, }; }
Collections as 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
Create an object with a Mixed value by using the new operator within a write transaction.
Example
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 thenew
operator to create a new realm object within a write transaction. Each of theCat
objects uses a different data type for thebirthDate
property.Use the
useQuery()
hook to retrieve allCat
objects.Map through the cats to render a list of
Text
components displaying each cat'sname
andbirthDate
.
1 const 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 };
1 const 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 };
Query for Objects with a Mixed Value
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.
Example
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 theCat
class to theuseQuery()
hook, and then usefiltered()
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".
1 const 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 };
1 type CatInfoCardProps = {catName: string}; 2 3 const 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 };
Mixed Properties and Type Checking
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>; } };