Defining a field with different schema types

  1. How do i define if a particular field can be array of one or more schema types ( for example - You have a person schema where pets field could be array of cats ( cats ) or array of dogs ( dogs ) . From what I learnt earlier there was type “Union” to specify it can hold schema of different types and now union throws error .
  2. Should embedded objects also be part of realm config schema ?

In Realm, you will be using a list data type. It behaves very similar to an array and in fact list maps to the JavaScript Array type. You can also specify that a field contains a list of primitive value type by appending [] to the type name.

You should also investigate the mixed property type - it can hold different data types.

Clicking through the above links will likely answer your question more effectively and completely than an answer here.

Embedded objects are managed and part of an objects schema. But realm config schema is a bit vague. Can you claify what you’re asking, perhaps provide a use case?

1 Like

Ahhh! I use list data type to specify array . From what i see [mixed] data type doesn’t serve my purpose . I’m looking to achieve something like this - type union with different data types


(https://www.mongodb.com/docs/realm/sdk/react-native/realm-database/schemas/mixed/)

Are you asking about

info: {type: 'union', objectTypes: [ 'string', 'int', 'Person']

If so, isn’t that just a List of more mixed types?

(in the future, please post code as text and use the formatting </> feature, and not screen shots)

I’m looking to implement something like this - schema type - list , object type - Object . For reference the ‘children’ field in below code

export class HubSection extends Realm.Object {
  static schema = {
    name: 'hubSection',
    properties: {
      id:'objectId',
      title: 'string', 
      entityType: 'string',
      layoutStyle: 'string',
      cardStyle: 'string',
      showFilter: 'bool',
      userDefined: 'bool',
      children: 'mixed[]',
      // children: { type: "list", objectType: "mixed" },
    },
  };
}

Note: And , this line of code throws error 'children: { type: "list", objectType: "mixed" } ' . But this is supported by docs here [https://github.com/realm/realm-js/issues/3389](https://github.com/realm/realm-js/issues/3389)

What error is it throwing? When does the error occur?

The post does say

Only the following types are supported: int , bool , float , double , string , data , date , objectId , uuid , decimal128 and links. Realm.create() will validate input accordingly.

Ahhh ! It throws an error saying ’ Object type should be string ’ . And my usecase is I need to have list where the object type is an object ( preferablly object type should be a custom defined schema type like “person” )

If I understand your goal, what you’d like to have is a field which of of type string | int | Person. I have a similar requirement, and from what I’ve found there’s no direct translation to the Realm model. You could use a Mixed type to represent string | int, but it would not capture the idea that the value is either a string or an int - instead it would just say "the value is of any type except a collection, eg a bool | int | float | double | string | ... | date.

The other problem is that a Mixed type can hold any type except a collection, and Person is a collection (a dictionary, to be precise). See Mixed - React Native SDK,

The mixed data type is a realm property type that can hold any valid Realm data type except a collection. You can create collections (lists, sets, and dictionaries) of type mixed , but a mixed type itself cannot be a collection.

The best solution I’ve found is to represent everything as a Dictionary of Mixed values. This is a bummer because you lose the structure of your Person schema, and in your case you’d have to wrap the string and int values inside an object. If there is a better out there please let me know, I’m new to Realm and trying to figure it out.

In my case what I’d like to have is something like Person | Alien | Superhero, eg a discriminated union of dictionary types. To get this to fit into the Realm model, it seems I have to use a Dictionary of Mixed values, so I lose any typing about the dictionary fields and the values must all be scalar values (not collections). Or else I could use a sparse dictionary via optional properties, something like

{
  _id: ObjectId,
  personData?: Person,
  alienData?: Alien,
  superheroData?: Superhero
}

Which is essentially converting a sum type into a product type, and not exactly ideal, but does maintain the typing of the variants at the cost of the typing of the union itself.

I know an answer but it’s in Swift as I am not a React guy.

TL:TR
Is there a direct translation from Swift SDK AnyRealmValue to a corresponding property in React? The reason is that AnyRealmValue supports all of the primitive types (int, string etc) but also supports object.

This may not be helpful but let me toss some Swift code out there to see if we can migrate it. Suppose we have a ZooClass object

class ZooClass: Object {
    @Persisted var animalList = RealmSwift.List<AnyRealmValue>()
}

that has a property that stores animals in a List object., animalList. The List object stores objects of AnyRealmValue (this zoo has dogs and cats only)

class DogClass: Object {
   @Persisted var name = ""
}

class CatClass: Object {
   @Persisted var name = ""
}

create a dog and a cat

let d = DogClass()
d.name = "spot"
let c = CatClass()
c.name = "fluffy"

then cast them to AnyRealmValue objects

let obj0: AnyRealmValue = .object(d)
let obj1: AnyRealmValue = .object(c)

Add those objects to our zoo.animalList and write to realm

anytownZoo.animalList.append(obj0)
anytownZoo.animalList.append(obj1)

try! realm.write {
   realm.add(anytownZoo)
}

from there when they are read from Realm, each object “knows” it’s object class and can then be cast back to it’s actual class

let zoo = realm.objects(ZooClass.self).first!

and then iterate over the list to identify each animal type and get it’s name

for animal in zoo.animalList {
    if let dog = animal.object(DogClass.self) {
        print("it was a dog named \(dog.name)")
    } else if let cat = animal.object(CatClass.self) {
        print("it was a cat named \(cat.name)")
    }
}

and the output

it was a dog named spot
it was a cat named fluffy

The key here is that AnyRealmValue allows a List to be un-homogenous (is that a word?) - storing different types of objects. This could be expanded to also contain ints, strings etc.

Now we need someone to translate that to into something usable in React.

Let me know if that was utterly useless, lol, and I will delete it.

That’s interesting, thanks for the reply, is this just a difference in the capabilities of the two SDK’s? I haven’t run across anything equivalent to Swift’s AnyRealmValue.

Maybe someone from Mongo can chime in, it would be quite useful if it is possible.