Realm does not seems to working - react-native

I am trying to use realm in react-native android and I just wanted to test if it is working or not.
It seems to save data since it throws duplicated primaryKey error.
However, realm.objects('Person') does not return data but
Proxy
[[Handler]]
:
Object
[[Target]]
:
Results
[[IsRevoked]]
:
false
class Person {}
Person.schema = {
name: 'Person',
primaryKey: 'name',
properties: {
name: 'string',
age: {type: 'int', default: 0},
},
};
const realm = new Realm({schema: [Person],schemaVersion: 2});
// Write
realm.write(() => {
const savedPerson = realm.create('Person', {
name: 'Hal Incanden1za',
age: 17,
});
});
console.log(realm.objects('Person'))

The value you get from a realm.objects() call is not a normal array, so console.log may not be doing what you are expecting here. Try iterating through it instead.

Related

How to store an Array of Arrays with Realm in React Native?

I want to store an array of arrays using Realm, but if I use type mixed it throws an error:
[Error: A mixed property cannot contain an array of values.]
This is my sample code:
export const ContentScheme = {
name: 'content',
primaryKey: 'elementId',
properties: {
elementId: 'string?',
currentTimeInfo: 'mixed',
}
}
Inserting Data:-
let data = {
elementId: '60d19799c0023702d41c1110',
currentTimeInfo:[["03.41", "03.29"], ["03.30", "05.14"], ["05.18", "00.00"]]
}
For my approach, I will create another schema CurrentTimeSchema and store it as array in ContentSchema.
Here is the solution.
export const ContentScheme = {
name: 'content',
primaryKey: 'elementId',
properties: {
elementId: 'string?',
currentTimeInfo: 'CurrentTime[]', <-- store CurrentTime in []
}
}
export const CurrentTimeSchema = {
name: 'CurrentTime',
embedded: true, <-- avoid creating new object of CurrentTime
properties: {
time1: 'string?', <-- rename these
time2: 'string?',
}
};

Using nested include on an array

I am trying to verify that an array has 2 elements with the following values:
expect([{
createdAt: 1545588925941,
updatedAt: 1545588925941,
id: '5c1fd0bdd38b1b2bb0875dd9',
readAt: null,
type: 'ResidentCreatedTask',
dataVersion: 0,
data: '{}',
user: '5c1fd0bdd38b1b2bb0875dd6',
home: '5c1fd0bdd38b1b2bb0875dd8'
},
{
createdAt: 1545588925941,
updatedAt: 1545588925941,
id: '5c1fd0bdd38b1b2bb0875dd9',
readAt: null,
type: 'ResidentCreatedTask',
dataVersion: 0,
data: '{}',
user: '5c1fd0bdd38b1b2bb0875dd6',
home: '5c1fd0bdd38b1b2bb0875dd8'
}
]).to.be.an('array').that.has.lengthOf(2).and.to.deep.nested.include({
0: {
type: 'ResidentCreatedTask'
},
1: {
type: 'ResidentCreatedTask'
},
});
But it's not working. I also tried changing the keys to strings with brackets like '[0]' and '[1]'.
I also tried removing the keys and making the val of includes an array like this:
.include([{ type: 'ResidentCreatedTask' }, { type: 'ResidentCreatedTask' }]);
But this also didn't work.
I don't like this solution, but you can wrap it an object.
So our payload is const payload = [{ id: 0 },{ id: 1 }]. Doing the following will not work, this is what I did in original post:
expect(payload).to.nested.include({ '[0].id': 0, '[1].id': 1 });
Work around is:
const wrappedPayload = { a: payload };
expect(wrappedPayload).to.nested.include({ 'a[0].id': 0, 'a[1].id': 1 });
This works, but I don't like having to wrap it. Very much still open to solutions. Is this a bug I should report to chai team?

Realm react native schema versioning

I have the following 2 schemas in realm.js file
class Bill extends Realm.Object {}
Bill.schema = {
name: 'Bill',
primaryKey: 'id',
properties: {
id: { type: 'string', indexed: true },
year: 'int',
month: 'int',
description: 'string',
dateCreated: 'int',
}
};
class User extends Realm.Object {}
User.schema = {
name: 'User',
primaryKey: 'id',
properties: {
id: 'string',
name: 'string?',
email: 'string?'
}
};
const realm = new Realm({schema: [Bill, User]});
export default realm;
this works perfectly when I first release my app to AppStore or PlayStore.
I need to change both schema and release to AppStore or PlayStore again and I need to handle both new installation or update of my app where the schema change to following
class Bill extends Realm.Object {}
Bill.schema = {
name: 'Bill',
primaryKey: 'id',
properties: {
id: { type: 'string', indexed: true },
year: 'int',
month: 'int',
description: 'string',
dateCreated: 'int',
dateDeleted: 'int',
}
};
class User extends Realm.Object {}
User.schema = {
name: 'User',
primaryKey: 'id',
properties: {
id: 'string',
name: 'string?',
email: 'string?',
photoUrl: 'string?',
}
};
by adding one more field in each schema.
So how should I configure my realm schema version?
Should I configure like below:
const realm = new Realm([
{schema: Bill, schemaVersion: 1},
{schema: User, schemaVersion: 1}
]);
But this may crash for new installation.
You should set global schemaVersion for all database, not for each model. And perform migrations to the current version, like it's described in the docs:
You define a migration and the associated schema version by updating
the schemaVersion and defining an optional migration function. Your
migration function provides any logic needed to convert data models
from previous schemas to the new schema. When opening a Realm the
migration function will be applied to update the Realm to the given
schema version only if a migration is needed.
If no migration function is supplied then any new properties an
automatically added and old properties are removed from the database
when updating to the new schemaVersion. If you need to update old or
populate new properties when upgrading your version you can do this in
the migration function. For example, suppose we want to migrate the
Person model declared earlier. You can populate the name property of
the new schema using the old firstName and lastName properties:
Realm.open({
schema: [PersonSchema],
schemaVersion: 1,
migration: (oldRealm, newRealm) => {
// only apply this change if upgrading to schemaVersion 1
if (oldRealm.schemaVersion < 1) {
const oldObjects = oldRealm.objects('Person');
const newObjects = newRealm.objects('Person');
// loop through all objects and set the name property in the new schema
for (let i = 0; i < oldObjects.length; i++) {
newObjects[i].name = oldObjects[i].firstName + ' ' + oldObjects[i].lastName;
}
}
}
}).then(realm => {
const fullName = realm.objects('Person')[0].name;
});
Once the migration is successfully completed the Realm and all of its
objects can be accessed as usual by your app.

Realm React Native: How remove element from object's nested array with some condition

I am new in React native and trying to integrate Realm as a client side DB.
I have 2 schemas:
export const CAR_SCHEMA = {
name: 'Car',
properties: {
color: 'string',
model: 'string',
}
};
export const PERSONS_SCHEMA = {
name: 'Person',
primaryKey: 'id',
properties: {
id: 'int',
firstName: 'string',
lastName: 'string'
cars: 'Cars[]'
}
};
My question basically means how to remove 'Car' from 'Person' where Car.model='Honda'? I couldn't find any documentation about deleting element from object's nested array.
Remove from array but keep item in Realm:
realm.write(() => {
let person = realm.objectForPrimaryKey('person', personId);
let carsOfPerson = person.cars;
var i = carsOfPerson.length - 1;
while(i >= 0) {
if(carsOfPerson[i].model == "Honda") {
carsOfPerson.splice(i, 1);
}
i--;
}
});
Remove from array by deleting item from Realm:
realm.write(() => {
let person = realm.objectForPrimaryKey('person', personId);
let carsOfPerson = person.cars;
let hondasOfPerson = carsOfPerson.filtered('model = "HONDA"')
realm.delete(hondasOfPerson)
});

how to use react-native realm

I started to use realm in my project and I have a question about retrieving the data. When I make a call to query all of the objects in my Subdivision model the return result includes the get/set methods. I must parse and stringify this before I am able to use it. I have read the docs and I do not see anything about this. Is this something that has to be done or am I missing something?
Model
class Subdivision extends Realm.Object { }
Subdivision.schema = {
name: 'Subdivision',
primaryKey: 'id',
properties: {
id: 'int',
subdivisionName: 'string',
latitude: 'float',
longitude: 'float',
status: 'string',
statusFlag: 'string',
marketId: 'int',
color: { type: 'int', optional: true },
colorStr: { type: 'string', optional: true }
}
};
Setting Subdivisions
_.each(response, (item) => {
Realm.write(() => {
Realm.create('Subdivision', item);
});
});
Getting Subdivisions
let result = Realm.objects('Subdivision');
let strRes = JSON.parse(JSON.stringify(result))
You shouldn't have to call JSON.stringify on result. Realm.objects returns a Results object which functions very similiarly to a JS Array: https://realm.io/docs/react-native/0.13.0/api/Realm.Results.html
You should be able to access each result using subscript indexing or other JS enumerations methods, ie result[0], or results.forEach((subidv) => {...}) etc.