realm / realm-js

Realm is a mobile database: an alternative to SQLite & key-value stores
https://realm.io
Apache License 2.0
5.8k stars 577 forks source link

Error creating an object with a property of array of strings #4119

Open kraenhansen opened 2 years ago

kraenhansen commented 2 years ago

In my case updating to that alpha generates an error when creating an object with a property of array of strings, ie:

realm.create(
          'Entity',
          {categories: ['personal']},
          UpdateMode.Modified
        );

gives:

Error: Exception in HostFunction: Entity.categories must be of type 'string[]', got 'object' (personal), js engine: hermes

but, interestingly, everything persists correctly.

But the good news is that now Realm works perfectly with Reanimated 2, reload works without a crash, so I believe that issue could be closed soon: https://github.com/software-mansion/react-native-reanimated/issues/1424

Originally posted by @somebody32 in https://github.com/realm/realm~~js/discussions/3978#discussioncomment~~1604048

somebody32 commented 2 years ago

I just tried with the latest alpha (10.20.0-alpha.2), and it still happens

somebody32 commented 2 years ago

@fronck @kraenhansen I finally have managed to nail the root cause of it. It looks like it is an edge case of the difference between proxy implementation in hermes/jsc.

Here is the failing code (modified TS Realm example)

  1. added categories: string[] to Task schema
    static schema = {
    name: 'Task',
    primaryKey: 'id',
    properties: {
      id: 'string',
      description: 'string',
      isComplete: {type: 'bool', default: false},
      categories: 'string[]',
    },
    };
  2. modified Task.generate to include categories: ['test']
    static generate(description: string) {
    return {
      id: new Realm.BSON.ObjectId().toString(),
      description,
      isComplete: false,
      categories: ['test'],
    };
    }
  3. when creating a task I'm using immer's draft as a proxied version of the original data:
    import produce from "immer"
    const realm = realmRef.current;
    let task = Task.generate(description);
    produce(task, draft => {
    realm?.write(() => {
    realm?.create('Task', draft, 'modified');
    });
    });

it blows up with Error: Exception in HostFunction: Task.categories must be of type 'string[]', got 'object' (test), js engine: hermes

I agree that it looks like a real edge-case, but it works in JSC and the last Realm version without a problem, so maybe it should be treated as a regression. Meanwhile, userland fix is straightforward: creating a new array before writing: categories = [...categories]

gabrielporcher commented 2 years ago

So that is a bug? I'm using "realm": "^10.20.0-beta.1" and got the very same error than @kraenhansen

juanbalofredo commented 11 months ago

Just add a validation before creating the instance, i just did that: try { realm.write(() => { items.forEach((item) => { if (tableName === "Users") { item.favourite_talents ??= []; item.favourite_events ??= []; item.buddies ??= []; item.badges ??= []; } realm.create(tableName, item, true); }); }); console.log("Insertion successful: ", tableName); } catch (error) { console.error("Error inserting into table:", tableName, error); throw error; } };

instead of item.favourite_talents and all that, add your personal items that you are having your problem with