[Realm React: Arrays] Schema Validation Error: Property 'Object.key' of type 'object' has unknown object type 'Array'

Hello, I am trying to define a schema (using TypeScript) and I am encountering the following error:

Error: Exception in HostFunction: Schema validation failed due to the following errors:

- Property 'SomeObject.testKey' of type 'object' has unknown object type 'Array' 

This is vaguely what the schema looks like, as I’ve defined it:

export class SomeObject extends Realm.Object<SomeObject> {
  _id!: Realm.BSON.UUID = new Realm.BSON.UUID();
  userId!: string;
  name!: string;
  createdAt!: Date = new Date();
  lastUpdated!: Date = new Date();
  testObject: EmbeddedObjectClass;
  testKey?: Array<SomeClass>; 
  // Realm.List leads to the same error
  // except with "List" instead of "Array" as the unknown object type

  static generate({name, userId=NO_SYNC_USER_ID} testObject, testKey=[]}: {
    name: string,
    userId: string | undefined,
    testObject: EmbeddedObjectClass,
    testKey: Array<SomeClass>
  }) {
    return {
      name,
      userId: userId,
      testObject: testObject
      testKey: testKey,
    }
  }
}

So I’ve somehow gotten embedded objects to work, and I can somewhat simulate an array using an embedded object (arrays in documents are meant to be limited, so having predefined keys isn’t the worst thing in the world), but I can’t seem to get lists or JavaScript Arrays to work—which would be much easier (and perhaps optimal?) to work with.

For me, the big question is: How do I get lists/arrays to work in Realm—how do I write lists to documents?

Note, also, that if I set the type, testKey: any or testKey: SomeClass[], and pass an array of SomeClass objects in the constructor, I get a silent failure: the application runs, nothing crashes, I don’t get an error message, but the array never gets written to the resultant Realm object/document.

I also cannot define a separate, static schema = {...}, as this leads to the following error:

[Error: TransformError <path_to_file_defining_schema_class>: 
Classes extending Realm.Object cannot define their own `schema` static, 
all properties must be defined using TypeScript syntax]

Hi again, @Alexander_Ye! I really appreciate you bringing your concerns here. I think the Embedded Objects page I linked you to in the other post may have lead you astray. Apologies! There are a few things we need to look at in your schema:

  • In Realm Database, you need to use Realm primitives to define your schemas. For TypeScript, this would mean you define an array something like this: publisher!: Realm.List<Publisher>. That is, state the Realm Database primitive, then pass the type.
  • You shouldn’t define static schema when using TypeScript and @realm/react. That’s only necessary for JS classes. I think the docs may have lead you astray here.
  • Instead of static generate, consider using a constructor.

Here’s a complex schema from a personal project. I wouldn’t necessarily consider this best practice (I’m a TypeScript novice), but hopefully it helps illustrate the embedded object and array syntax.

I’ll work on making this clearer in the new React Native SDK docs. All of this was a personal pain point for me when I joined the team a few months ago.

1 Like

Re: my first bullet, it sounds like you tried the correct syntax, but List is an unknown type. Assuming you’ve imported things correctly, it could be an issue with how you’ve configured your realm. You need to pass all of your schema models into your realm config, including your embedded object schemas. See here in my personal project.

2 Likes

Hey @Kyle_Rollins, thanks for the assist.

When I use Realm.List instead of List, I no longer see the error. (I have passed all my schema models, including the embedded object schemas, into the realm config, but that’s a great reminder—thanks.)

My next question is how do I use a Realm List? More specifically:

How do I initialize a Realm List?

  • The docs indicate that the Realm List behaves similar to JavaScript arrays, but that they can only store objects of a single type.
  • If I initialize a Realm List like so: test: Realm.List<ObjectName> = new Realm.List(), I encounter the following error (crashes the app):
TypeError: Illegal constructor
  • If I initialize a Realm List like so: test: Realm.List<ObjectName> = [], I encounter the following type (does not crash the app) error:
Type 'undefined[]' is missing the following properties from type 
'List<ObjectName>': type, optional, toJSON, description, and 12 more.
  • Conversely, if I initialize the list like so: test: ObjectName[] = [], I encounter the following type error when I attempt to set the Realm document:
Type 'ObjectName[]' is missing the following properties from type 
'List<RecentSpeaker>': type, optional, toJSON, description, and 12 more.

Apologies, @Alexander_Ye. Work and life got busy. If you’ve worked this out already, please disregard!

In your data model, you don’t initialize the Realm List. That happens when you create a new instance of your object class. You can only write data to a realm inside of realm.write().

So, a contrived example using some of the wording from your example:

  realm.write(() => {
    // New instance of your SomeObject class/realm object
    const newListParentObject = new SomeObject(
    	realm,
    	// other things you asserted in your SomeObject model would exist
    );
    
    // New instance of realm object that you're adding to your Realm List
    const newListItemObject = new SomeClass(
      realm,
      // other things you asserted in your SomeClass model would exist
    )
  
    // Push your new list item to your Realm List
    newListParentObject.testKey.push(newListItemObject);
  });

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.