One to many relationship in realm react - react-native

Im using realm/react to build a synced mobile app and used this template to start building:
https://github.com/realm/realm-js/tree/master/templates/react-native-template-realm-js
Now im trying to implement an embedded array of objects like it in the documentation:
https://www.mongodb.com/docs/realm/sdk/react-native/data-types/embedded-objects/#realm-object-models
My schema looks like this:
import {Realm} from '#realm/react';
import {ObjectId} from 'bson';
export class Media extends Realm.Object {
constructor(
realm,
userId,
collectionType,
type,
genre,
mediaName,
author,
releaseDate,
language,
length,
link,
note,
) {
super(realm, {
_id: new ObjectId(),
userId: userId || '_SYNC_DISABLED_',
collectionType: 'collection',
type: 'test data',
genre: 'test data',
mediaName: 'test data',
author: 'test data',
releaseDate: 'test data',
language: 'test data',
length: 'test data',
link: 'test data',
note: 'test data',
createdAt: new Date(),
access: [userId],
});
}
static Mediaschema = {
name: 'Media_media',
embedded: true,
properties: {
//_id: 'objectId',
author: 'string?',
createdAt: 'string?',
genre: 'string?',
language: 'string?',
length: 'int?',
link: 'string?',
mediaName: 'string?',
note: 'string?',
releaseDate: 'string?',
type: 'string?',
},
};
static schema = {
name: 'Media',
properties: {
_id: 'objectId?',
access: 'string[]',
collectionType: 'string?',
media: {type: 'list', objectType: 'Media_media'},
userId: 'string?',
},
primaryKey: '_id',
};
}
Then i import the schemas like this:
import {createRealmContext} from '#realm/react';
import {Media} from './Media';
export const MediaRealmContext = createRealmContext({
schema: [Media.schema, Media.Mediaschema],
});
but i get the following error that i can’t get rid of:
ERROR Error: Exception in HostFunction: Constructor was not registered in the schema for this Realm
This error is located at:
in AppSync (created by AppWrapperSync)
in Unknown (created by AppWrapperSync)
in UserProvider (created by AppWrapperSync)
in AppProvider (created by AppWrapperSync)
in RCTView (created by View)
in View (created by AppWrapperSync)
in AppWrapperSync (created by App)
in App
in RCTView (created by View)
in View (created by AppContainer)
in RCTView (created by View)
in View (created by AppContainer)
in AppContainer
in youria(RootComponent)
ERROR [Error: Exception in HostFunction: Constructor was not registered in the schema for this Realm]
Everything works just like i want it, when i am working with just an plain object without embedding anything.
I would appreciate any help!

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?',
}
};

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 does not seems to working

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.

backbone-forms giving error as Uncaught TypeError: t is not a constructor

I am working with JSON Schema and backbone forms for the first time. I have copied the same example as mentioned in backbone forms but it is giving error as shown below:
The code is mentioned below :
var registerForm = Backbone.Model.extend({
schema:{
title: { type: 'Select', options: ['Mr', 'Mrs', 'Ms'] },
name: 'Text',
email: { validators: ['required', 'email'] },
birthday: 'Date',
password: 'Password',
notes: { type: 'List', itemType: 'Text' }
}
});
var user = new registerForm();
var form = new Backbone.Form({
model: user
}).render(); $('body').append(form.el);
Please help me to resolve this issue.
You cannot include List editor. This is a special editor which is in a separate file and must be included:
<script type="text/javascript" src="backbone-forms/distribution/editors/list.js" />
https://github.com/powmedia/backbone-forms#list

Mongoose Post with Mixed/Geospatial Schemas

Hello i'm using Mongoose and Express to submit geospatial data for a map (GEOJSON).
I have a form which gets the longitude and latitude for a point and the user can then submit to save this point.
My form works if I hard code the values in the 'coordinates' part of my post route, but if I try to do req.body.longitude and req.body.latitude it doesnt post to the array and gets me a 'req not defined' error.
I picked up the basics of mongoose geojson here:
https://gist.github.com/aheckmann/5241574
How can I make this form save from req.body values in a mixed schema? Thanks.
My Schema
var schema = new Schema({
type: {type: String},
properties: {
popupContent: {type: String}
},
geometry: {
type: { type: String }
, coordinates: {}
}
});
schema.index({ geometry: '2dsphere' });
var A = mongoose.model('A', schema);
My Post Route
app.post('/api/map', function( request, response ) {
console.log("Posting a Marker");
var sticker = new A({
type: 'Feature',
properties: {
popupContent: 'compa'
},
geometry: {
type: 'Point',
coordinates: [req.body.longitude, req.body.latitude]
}
});
sticker.save();
return response.send( sticker );
res.redirect('/map')
});
My Clientside Form
form(method='post', action='/api/map')
input#popup(type="text", value="click a button", name="popup")
input#lng(type="text", value="click a button", name="longtude")
input#lat(type="text", value="click a button", name="latitude")
input(type="submit")
Your function signature states that there is no req parameter.
app.post('/api/map', function( request, response )
You should either rename your parameters in your signature or in the body.
app.post('/api/map', function(request, response) {
console.log("Posting a Marker");
var sticker = new A({
type: 'Feature',
properties: {
popupContent: 'compa'
},
geometry: {
type: 'Point',
coordinates: [request.body.longitude, request.body.latitude]
}
});
sticker.save();
return response.send(sticker);
});
Uh, just seen this thread is dusty. Well…