Skip to content

Commit ff70e2f

Browse files
Mohammad Hunan ChughtaiMohammad Hunan Chughtai
andauthored
(DOCSP-26985): @realm/reactify: UUID - React Native SDK (#2443)
## Pull Request Info ### Jira - https://jira.mongodb.org/browse/DOCSP-26985 ### Staged Changes - [UUID - React Native SDK](https://docs-mongodbcom-staging.corp.mongodb.com/realm/docsworker-xlarge/DOCSP-26985-uuid-object/sdk/react-native/realm-database/schemas/uuid/) ### Reminder Checklist If your PR modifies the docs, you might need to also update some corresponding pages. Check if completed or N/A. - [N/A] Create Jira ticket for corresponding docs-app-services update(s), if any - [N/A] Checked/updated Admin API - [N/A] Checked/updated CLI reference ### Review Guidelines [REVIEWING.md](https://github.com/mongodb/docs-realm/blob/master/REVIEWING.md) Co-authored-by: Mohammad Hunan Chughtai <[email protected]>
1 parent 6e17388 commit ff70e2f

File tree

9 files changed

+334
-10
lines changed

9 files changed

+334
-10
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import Realm from 'realm';
2+
// :snippet-start: js-profile-schema
3+
class Profile extends Realm.Object {
4+
static schema = {
5+
name: 'Profile',
6+
primaryKey: '_id',
7+
properties: {
8+
_id: 'uuid',
9+
name: 'string',
10+
},
11+
};
12+
}
13+
// :snippet-end:
14+
export default Profile;
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import React, {useState} from 'react';
2+
import {Button, TextInput, View} from 'react-native';
3+
import {render, fireEvent, waitFor, act} from '@testing-library/react-native';
4+
import Realm from 'realm';
5+
import {createRealmContext} from '@realm/react';
6+
import Profile from '../../models/Profile';
7+
8+
const realmConfig = {
9+
schema: [Profile],
10+
deleteRealmIfMigrationNeeded: true,
11+
};
12+
13+
const {RealmProvider, useRealm} = createRealmContext(realmConfig);
14+
15+
let assertionRealm;
16+
17+
// test describe block for the uuid schema
18+
describe('uuid schema', () => {
19+
beforeEach(async () => {
20+
// we will use this Realm for assertions to access Realm Objects outside of a Functional Component (like required by @realm/react)
21+
assertionRealm = await Realm.open(realmConfig);
22+
23+
// delete every object in the realmConfig in the Realm to make test idempotent
24+
assertionRealm.write(() => {
25+
assertionRealm.delete(assertionRealm.objects(Profile));
26+
27+
new Profile(assertionRealm, {
28+
name: 'Tony Stark',
29+
_id: new Realm.BSON.UUID(),
30+
});
31+
});
32+
});
33+
afterAll(() => {
34+
if (!assertionRealm.isClosed) {
35+
assertionRealm.close();
36+
}
37+
});
38+
39+
it('should be able to create a new uuid', async () => {
40+
// :snippet-start: create-uuid-object
41+
// :replace-start: {
42+
// "terms": {
43+
// " testID='nameInput'": "",
44+
// " testID='createProfileButton'": ""
45+
// }
46+
// }
47+
const CreateProfileInput = () => {
48+
const realm = useRealm();
49+
const [name, setName] = useState('');
50+
51+
// createProfile creates a new 'Profile' Realm Object with a new UUID based on user input
52+
const createProfile = () => {
53+
realm.write(() => {
54+
new Profile(realm, {
55+
name,
56+
_id: new Realm.BSON.UUID(),
57+
});
58+
});
59+
};
60+
return (
61+
<View>
62+
<TextInput testID='nameInput' placeholder='Name' onChangeText={setName} />
63+
<Button testID='createProfileButton' title='Create Profile' onPress={createProfile} />
64+
</View>
65+
);
66+
// :replace-end:
67+
// :snippet-end:
68+
};
69+
const App = () => (
70+
<RealmProvider>
71+
<CreateProfileInput />
72+
</RealmProvider>
73+
);
74+
75+
const {getByTestId} = render(<App />);
76+
77+
// Test that the createProfileButton's onPress method creates a new Profile Object with a new UUID
78+
const nameInput = await waitFor(() => getByTestId('nameInput'), {
79+
timeout: 5000,
80+
});
81+
const createProfileButton = await waitFor(() => getByTestId('createProfileButton'), {timeout: 5000});
82+
83+
await act(() => {
84+
fireEvent.changeText(nameInput, 'Steve Rogers');
85+
});
86+
await act(() => {
87+
fireEvent.press(createProfileButton);
88+
});
89+
90+
// Test that the Profile Object with the new UUID was created using the assertionRealm and that the name is correct
91+
const profiles = assertionRealm.objects(Profile);
92+
expect(profiles.length).toBe(2);
93+
expect(profiles[1].name).toBe('Steve Rogers');
94+
});
95+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import Realm from 'realm';
2+
// TODO: Replace `static schema` with TS-first models + realm-babel-plugin (https://www.npmjs.com/package/@realm/babel-plugin) approach once realm-babel-plugin version 0.1.2 releases with bug fixes
3+
// :snippet-start: ts-profile-schema
4+
class Profile extends Realm.Object<Profile> {
5+
_id!: Realm.BSON.UUID;
6+
name!: string;
7+
8+
static schema = {
9+
name: 'Profile',
10+
primaryKey: '_id',
11+
properties: {
12+
_id: 'uuid',
13+
name: 'string',
14+
},
15+
};
16+
}
17+
// :snippet-end:
18+
export default Profile;
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import React, {useState} from 'react';
2+
import {Button, TextInput, View} from 'react-native';
3+
import {render, fireEvent, waitFor, act} from '@testing-library/react-native';
4+
import Realm from 'realm';
5+
import {createRealmContext} from '@realm/react';
6+
import Profile from '../../models/Profile';
7+
8+
const realmConfig = {
9+
schema: [Profile],
10+
deleteRealmIfMigrationNeeded: true,
11+
};
12+
13+
const {RealmProvider, useRealm} = createRealmContext(realmConfig);
14+
15+
let assertionRealm: Realm;
16+
17+
// test describe block for the uuid schema
18+
describe('uuid schema', () => {
19+
beforeEach(async () => {
20+
// we will use this Realm for assertions to access Realm Objects outside of a Functional Component (like required by @realm/react)
21+
assertionRealm = await Realm.open(realmConfig);
22+
23+
// delete every object in the realmConfig in the Realm to make test idempotent
24+
assertionRealm.write(() => {
25+
assertionRealm.delete(assertionRealm.objects(Profile));
26+
27+
new Profile(assertionRealm, {
28+
name: 'Tony Stark',
29+
_id: new Realm.BSON.UUID(),
30+
});
31+
});
32+
});
33+
afterAll(() => {
34+
if (!assertionRealm.isClosed) {
35+
assertionRealm.close();
36+
}
37+
});
38+
39+
it('should be able to create a new uuid', async () => {
40+
// :snippet-start: create-uuid-object
41+
// :replace-start: {
42+
// "terms": {
43+
// " testID='nameInput'": "",
44+
// " testID='createProfileButton'": ""
45+
// }
46+
// }
47+
const CreateProfileInput = () => {
48+
const realm = useRealm();
49+
const [name, setName] = useState('');
50+
51+
// createProfile creates a new 'Profile' Realm Object with a new UUID based on user input
52+
const createProfile = () => {
53+
realm.write(() => {
54+
new Profile(realm, {
55+
name,
56+
_id: new Realm.BSON.UUID(),
57+
});
58+
});
59+
};
60+
return (
61+
<View>
62+
<TextInput testID='nameInput' placeholder='Name' onChangeText={setName} />
63+
<Button testID='createProfileButton' title='Create Profile' onPress={createProfile} />
64+
</View>
65+
);
66+
// :replace-end:
67+
// :snippet-end:
68+
};
69+
const App = () => (
70+
<RealmProvider>
71+
<CreateProfileInput />
72+
</RealmProvider>
73+
);
74+
75+
const {getByTestId} = render(<App />);
76+
77+
// Test that the createProfileButton's onPress method creates a new Profile Object with a new UUID
78+
const nameInput = await waitFor(() => getByTestId('nameInput'), {
79+
timeout: 5000,
80+
});
81+
const createProfileButton = await waitFor(() => getByTestId('createProfileButton'), {timeout: 5000});
82+
83+
await act(() => {
84+
fireEvent.changeText(nameInput, 'Steve Rogers');
85+
});
86+
await act(() => {
87+
fireEvent.press(createProfileButton);
88+
});
89+
90+
// Test that the Profile Object with the new UUID was created using the assertionRealm and that the name is correct
91+
const profiles = assertionRealm.objects(Profile);
92+
expect(profiles.length).toBe(2);
93+
expect(profiles[1].name).toBe('Steve Rogers');
94+
});
95+
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class Profile extends Realm.Object {
2+
static schema = {
3+
name: 'Profile',
4+
primaryKey: '_id',
5+
properties: {
6+
_id: 'uuid',
7+
name: 'string',
8+
},
9+
};
10+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const CreateProfileInput = () => {
2+
const realm = useRealm();
3+
const [name, setName] = useState('');
4+
5+
// createProfile creates a new 'Profile' Realm Object with a new UUID based on user input
6+
const createProfile = () => {
7+
realm.write(() => {
8+
new Profile(realm, {
9+
name,
10+
_id: new Realm.BSON.UUID(),
11+
});
12+
});
13+
};
14+
return (
15+
<View>
16+
<TextInput placeholder='Name' onChangeText={setName} />
17+
<Button title='Create Profile' onPress={createProfile} />
18+
</View>
19+
);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class Profile extends Realm.Object<Profile> {
2+
_id!: Realm.BSON.UUID;
3+
name!: string;
4+
5+
static schema = {
6+
name: 'Profile',
7+
primaryKey: '_id',
8+
properties: {
9+
_id: 'uuid',
10+
name: 'string',
11+
},
12+
};
13+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const CreateProfileInput = () => {
2+
const realm = useRealm();
3+
const [name, setName] = useState('');
4+
5+
// createProfile creates a new 'Profile' Realm Object with a new UUID based on user input
6+
const createProfile = () => {
7+
realm.write(() => {
8+
new Profile(realm, {
9+
name,
10+
_id: new Realm.BSON.UUID(),
11+
});
12+
});
13+
};
14+
return (
15+
<View>
16+
<TextInput placeholder='Name' onChangeText={setName} />
17+
<Button title='Create Profile' onPress={createProfile} />
18+
</View>
19+
);

source/sdk/react-native/realm-database/schemas/uuid.txt

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,59 @@ Overview
1616

1717
``UUID`` (Universal Unique Identifier) is a 16-byte :wikipedia:`unique value
1818
<Universally_unique_identifier>`. You can use ``UUID`` as an identifier for
19-
objects. ``UUID`` is :ref:`indexable <react-native-indexes>` and you can use it as a
19+
objects. ``UUID`` is :ref:`indexable <react-native-indexes>`, and you can use it as a
2020
:ref:`primary key <react-native-primary-keys>`.
2121

22-
.. include:: /includes/note-using-uuid-instead-of-objectid.rst
22+
.. tabs-realm-languages::
23+
24+
.. tab::
25+
:tabid: typescript
26+
27+
.. literalinclude:: /examples/generated/react-native/ts/Profile.snippet.ts-profile-schema.ts
28+
:language: typescript
29+
30+
.. tab::
31+
:tabid: javascript
32+
33+
.. literalinclude:: /examples/generated/react-native/js/Profile.snippet.js-profile-schema.js
34+
:language: javascript
2335

2436
Usage
2537
-----
26-
To define a property as a ``UUID``, set its type to the string ``"uuid"`` in
27-
your :ref:`object model <react-native-object-schemas>`. Create a Realm
28-
object within a write transaction. To set any unique identifier properties of
29-
your object to a random value, call ``new UUID()``. Alternatively, pass a string
30-
to ``new UUID()`` to set the unique identifier property to a specific value.
31-
32-
.. literalinclude:: /examples/generated/node/data-types.snippet.work-with-uuid.js
33-
:language: javascript
38+
To define a property as a ``UUID``, set its type to ``"uuid"`` in your
39+
:ref:`object model <react-native-object-schemas>`. Create a Realm object within
40+
a write transaction. To set any unique identifier properties of your object to a
41+
random value, call ``new UUID()``. Alternatively, pass a string to ``new
42+
UUID()`` to set the unique identifier property to a specific value.
43+
44+
Example
45+
~~~~~~~
46+
47+
In the following ``CreateProfileInput`` example, we create a ``Profile``
48+
:js-sdk:`Realm.Object <Realm.Object.html>` with a ``uuid`` type for the ``_id``
49+
field.
50+
51+
The ``CreateProfileInput`` component does the following:
52+
53+
- Gets access to the opened realm instance by calling the ``useRealm()`` hook.
54+
- Creates a name `state variable <https://reactjs.org/docs/hooks-state.html>`__ called "name" that represents the name of the profile.
55+
- Creates a ``createProfile`` method that performs a write transaction. Within that write transaction, we :ref:`create <react-native-create-a-new-object>` a ``Profile`` object with the ``name`` value of the "name" state variable and an ``_id`` value of a new ``UUID`` object.
56+
- Renders a ``TextInput`` component that allows the user to enter a name for the profile. When the user presses the "Create Profile" button, the ``createProfile`` method is called and creates a ``Profile`` object.
57+
58+
.. tabs-realm-languages::
59+
60+
.. tab::
61+
:tabid: typescript
62+
63+
.. literalinclude:: /examples/generated/react-native/ts/uuid.test.snippet.create-uuid-object.tsx
64+
:language: typescript
65+
:emphasize-lines: 2, 7-12
66+
:linenos:
67+
68+
.. tab::
69+
:tabid: javascript
70+
71+
.. literalinclude:: /examples/generated/react-native/js/uuid.test.snippet.create-uuid-object.jsx
72+
:language: javascript
73+
:emphasize-lines: 2, 7-12
74+
:linenos:

0 commit comments

Comments
 (0)