-
Type: Bug
-
Resolution: Unresolved
-
Priority: Minor - P4
-
None
-
Affects Version/s: None
-
Component/s: Electron, Node.js, React Native
-
None
-
2 - S (<= 1 week)
-
6355
If resetting an embedded object to an object with e.g. a missing required property, the SDK expectedly throws. If this exception is caught within the write transaction by the user, the original embedded object will still be updated but with default values.
Since our call into Core's obj.create_and_set_linked_object() is made prior to setting the user-provided values, the values on the embedded object have been set to default values.
Example test (this test has already been set up by PR #6356):
Unable to find source-code formatter for language: ts. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
// Create a valid object with a valid embedded object (`address`). const amy = this.realm.write(() => { return this.realm.create(PersonWithEmbeddedSchema.name, { name: "Amy", age: 30, address: { street: "Broadway" }, }); }); expect(this.realm.objects(PersonWithEmbeddedSchema.name).length).equals(1); expect(amy.address?.street).equals("Broadway"); // Update the embedded object with an invalid one. this.realm.write(() => { // It is important to catch the exception within `realm.write()` in order to test // that the object creation path does not modify the object (rather than being due // to `realm.write()` cancelling the transaction). expect(() => { const invalidEmbeddedAddress = {}; // @ts-expect-error Testing setting invalid type. amy.address = invalidEmbeddedAddress; }).to.throw("Missing value for property 'street'"); }); const objects = this.realm.objects<IPersonWithEmbedded>(PersonWithEmbeddedSchema.name); expect(objects.length).equals(1); expect(objects[0].address).to.not.be.null; // Fails: `street` will be the default value (empty string). expect(objects[0].address?.street).equals("Broadway");