diff --git a/examples/node/Examples/data-types.js b/examples/node/Examples/data-types.js index cc1209df70..b80b0824c2 100644 --- a/examples/node/Examples/data-types.js +++ b/examples/node/Examples/data-types.js @@ -340,4 +340,92 @@ describe("Node.js Data Types", () => { // close the realm realm.close(); }); + test("should work with the Set data type", async () => { + // :code-block-start: define-set-objects + const characterSchema = { + name: "Character", + primaryKey: "_id", + properties: { + _id: "objectId", + name: "string", + levelsCompleted: "int<>", + inventory: "string<>", + }, + }; + // :code-block-end: + const realm = await Realm.open({ + schema: [characterSchema], + }); + + // :code-block-start: create-set-objects + let playerOne, playerTwo; + realm.write(() => { + playerOne = realm.create("Character", { + _id: new BSON.ObjectId(), + name: "PlayerOne", + inventory: ["elixir", "compass", "glowing shield"], + levelsCompleted: [4, 9], + }); + playerTwo = realm.create("Character", { + _id: new BSON.ObjectId(), + name: "PlayerTwo", + inventory: ["estus flask", "gloves", "rune"], + levelsCompleted: [1, 2, 5, 24], + }); + }); + // :code-block-end: + + expect(playerOne.inventory.has("elixir")).toBe(true); + expect(playerTwo.inventory.has("gloves")).toBe(true); + + // :code-block-start: add-items-to-set + realm.write(() => { + playerOne.inventory.add("hammer"); + playerOne.levelsCompleted.add(32); + }); + // :code-block-end: + + expect(playerOne.inventory.size).toBe(4); + expect(playerOne.levelsCompleted.size).toBe(3); + + // :code-block-start: check-if-set-has-items + // check if the playerTwo has completed level 3 by calling the `set.has()` method + const playerTwoHasCompletedLevelThree = playerTwo.levelsCompleted.has(3); + console.log( + `Is level three completed by the playerTwo: ${playerTwoHasCompletedLevelThree}` + ); + // :code-block-end: + expect(playerTwoHasCompletedLevelThree).toBe(false); + + // :code-block-start: remove-specific-item-from-set + realm.write(() => { + // remove the compass from playerOne's inventory by calling `set.delete()` within a write transaction + playerOne.inventory.delete("compass"); + }); + + // :code-block-end: + expect(playerOne.inventory.has("compass")).toBe(false); + + // :code-block-start: remove-all-items-from-set + realm.write(() => { + // clear all data from the inventory slot of the playerTwo by calling `set.clear()` in a write transaction + playerTwo.inventory.clear(); + }); + // :code-block-end: + + // :code-block-start: check-set-size + // check how many items the playerTwo has in his inventory through the `set.size` property + const playerTwoInventorySize = playerTwo.inventory.size; + console.log(`The playerTwo has ${playerTwoInventorySize} inventory items`); + // :code-block-end: + expect(playerTwo.inventory.size).toBe(0); + + // delete the object specifically created in this test to keep tests idempotent + realm.write(() => { + realm.delete(playerOne); + realm.delete(playerTwo); + }); + // close the realm + realm.close(); + }); }); diff --git a/source/examples/generated/node/data-types.codeblock.add-items-to-set.js b/source/examples/generated/node/data-types.codeblock.add-items-to-set.js new file mode 100644 index 0000000000..988cd8c26b --- /dev/null +++ b/source/examples/generated/node/data-types.codeblock.add-items-to-set.js @@ -0,0 +1,4 @@ +realm.write(() => { + characterOne.inventory.add("hammer"); + characterOne.levelsCompleted.add(32); +}); diff --git a/source/examples/generated/node/data-types.codeblock.check-if-set-has-items.js b/source/examples/generated/node/data-types.codeblock.check-if-set-has-items.js new file mode 100644 index 0000000000..0e09ea622d --- /dev/null +++ b/source/examples/generated/node/data-types.codeblock.check-if-set-has-items.js @@ -0,0 +1,5 @@ +// check if the characterTwo has completed level 3 by calling the `Realm.Set.has()` method +const characterTwoHasCompletedLevelThree = characterTwo.levelsCompleted.has(3); +console.log( + `Is level three completed by the characterTwo: ${characterTwoHasCompletedLevelThree}` +); diff --git a/source/examples/generated/node/data-types.codeblock.check-set-size.js b/source/examples/generated/node/data-types.codeblock.check-set-size.js new file mode 100644 index 0000000000..d864c79192 --- /dev/null +++ b/source/examples/generated/node/data-types.codeblock.check-set-size.js @@ -0,0 +1,3 @@ +// check how many items the characterTwo has in his inventory through the `Realm.Set.size` property +const characterTwoInventorySize = characterTwo.inventory.size; +console.log(`The characterTwo has ${characterTwoInventorySize} inventory items`); diff --git a/source/examples/generated/node/data-types.codeblock.create-set-objects.js b/source/examples/generated/node/data-types.codeblock.create-set-objects.js new file mode 100644 index 0000000000..dd47653332 --- /dev/null +++ b/source/examples/generated/node/data-types.codeblock.create-set-objects.js @@ -0,0 +1,15 @@ +let characterOne, characterTwo; +realm.write(() => { + characterOne = realm.create("Character", { + _id: new BSON.ObjectId(), + name: "CharacterOne", + inventory: ["elixir", "compass", "glowing shield"], + levelsCompleted: [4, 9], + }); + characterTwo = realm.create("Character", { + _id: new BSON.ObjectId(), + name: "CharacterTwo", + inventory: ["estus flask", "gloves", "rune"], + levelsCompleted: [1, 2, 5, 24], + }); +}); diff --git a/source/examples/generated/node/data-types.codeblock.define-set-objects.js b/source/examples/generated/node/data-types.codeblock.define-set-objects.js new file mode 100644 index 0000000000..e0bb37bf64 --- /dev/null +++ b/source/examples/generated/node/data-types.codeblock.define-set-objects.js @@ -0,0 +1,10 @@ +const characterSchema = { + name: "Character", + primaryKey: "_id", + properties: { + _id: "objectId", + name: "string", + levelsCompleted: "int<>", + inventory: "string<>", + }, +}; diff --git a/source/examples/generated/node/data-types.codeblock.remove-all-items-from-set.js b/source/examples/generated/node/data-types.codeblock.remove-all-items-from-set.js new file mode 100644 index 0000000000..4e4a5d0792 --- /dev/null +++ b/source/examples/generated/node/data-types.codeblock.remove-all-items-from-set.js @@ -0,0 +1,4 @@ +realm.write(() => { + // clear all data from the inventory slot of the characterTwo by calling `Realm.Set.clear()` in a write transaction + characterTwo.inventory.clear(); +}); diff --git a/source/examples/generated/node/data-types.codeblock.remove-specific-item-from-set.js b/source/examples/generated/node/data-types.codeblock.remove-specific-item-from-set.js new file mode 100644 index 0000000000..cec2514e5b --- /dev/null +++ b/source/examples/generated/node/data-types.codeblock.remove-specific-item-from-set.js @@ -0,0 +1,4 @@ +realm.write(() => { + // remove the compass from characterOne's inventory by calling `Realm.Set.delete()` within a write transaction + characterOne.inventory.delete("compass"); +}); diff --git a/source/sdk/node/data-types/sets.txt b/source/sdk/node/data-types/sets.txt index 5dc7b5b845..17ab6b948c 100644 --- a/source/sdk/node/data-types/sets.txt +++ b/source/sdk/node/data-types/sets.txt @@ -15,4 +15,98 @@ Sets - Node.js SDK .. versionadded:: 10.5.0-beta.1 Overview --------- \ No newline at end of file +-------- +A ``{+service-short+} Set`` is a special object that allows you to store a +collection of unique values. ``{+service-short+} Sets`` are based on JavaScript +:mdn:`sets `, but can only contain +values of a single type and can only be modified within a write transaction. +Sets allow you to perform math operations such as finding the union, +intersection, or difference between two sets. To learn more about performing +these operations, see the MDN docs for :mdn:`Implementing basic set operations +`. + +.. note:: ``{+service-short+} Sets`` Do Not Guarantee Traversal Order + + When using a ``forEach()`` loop or alternative :mdn:`iteration method + ` to traverse + the set in a loop, the content of the ``{+service-short+} Set`` may be in a + different order than originally written to. If you require an ordered version + of your set, you must implement that ordering yourself. If you require an + ordered version of your set, you must implement that order yourself. You can + do this by creating an array from the set, using :mdn:`Array.from(mySet) + ` or the :mdn:`spread + operator `. You can keep + that array updated by using a :ref:`change listener ` + to react to changes to the set. + + +.. _node-define-set-objects: + +Realm Object Models +------------------- +To define a property type as a ``{+service-short+} Set``, specify the data type +you want in the set, followed by ``<>``. For instance, for a set made of integer +values, specify ``"int<>"``. + +.. literalinclude:: /examples/generated/node/data-types.codeblock.define-set-objects.js + :language: javascript + +.. _node-create-set-objects: + +Create an Object With a Set +--------------------------- +To create an object with a ``{+service-short+} Set`` property, you must create +the object within a write transaction. When defining your {+service-short+} +object, initialize the ``{+service-short+} Set`` by passing an empty array or an +array with your initial values. + +.. literalinclude:: /examples/generated/node/data-types.codeblock.create-set-objects.js + :language: javascript + + +.. _node-add-items-to-set: + +Add Items to a Set +------------------ +To add an item to a set, pass the new value to the ``.add()`` method within a write transaction. + +.. literalinclude:: /examples/generated/node/data-types.codeblock.add-items-to-set.js + :language: javascript + +.. _node-check-if-set-has-items: + +Check if a Set has Specific Items +--------------------------------- +To determine if a set contains a particular value, pass the value to the ``.has()`` method. The +``set.has()`` method will return true if the set contains the value specified. + +.. literalinclude:: /examples/generated/node/data-types.codeblock.check-if-set-has-items.js + :language: javascript + +.. _node-check-set-size: + +Check the Size of a Set +----------------------- +To discover how many items are in a set, you can check the set's ``size`` property. + +.. literalinclude:: /examples/generated/node/data-types.codeblock.check-set-size.js + :language: javascript + +.. _node-remove-specific-item-from-set: + +Remove an Item from a Set +------------------------- +To remove a specific value from a set, pass the value to the ``.delete()`` method within a write transaction. + +.. literalinclude:: /examples/generated/node/data-types.codeblock.remove-specific-item-from-set.js + :language: javascript + + +.. _node-remove-all-items-from-set: + +Remove all Items from a Set +--------------------------- +To clear the set, run the ``.clear()`` method within a write transaction. + +.. literalinclude:: /examples/generated/node/data-types.codeblock.remove-all-items-from-set.js + :language: javascript