Which one is the best local database for react native apps? And what does facebook and instagram use to store data locally?
It's a nice question, but I don't know! but
I'm pretty sure that they use multiple NO-SQL DataBase for their server.
Anyway, If you are searching a local database for react-native
I will suggest you to use Realm -> https://realm.io/
It's use his own ORM and is build in Native for both platform IOS and Android, easy to use!
There some example: realm.js
import * as RealmDB from 'realm';
class Passenger extends RealmDB.Object {}
Passenger.schema = {
name: 'Passenger',
primaryKey: 'id',
properties: {
'id' : 'string',
'firstname' : { type: 'string', optional: true },
'lastname' : { type: 'string', optional: true },
'birthdate' : { type: 'int', optional: true },
'email' : { type: 'string', optional: true },
'phone' : { type: 'string', optional: true },
'child' : { type: 'linkingObjects', objectType: 'Child', property: 'passengers' }
}
};
class Travel extends RealmDB.Object {}
Travel.schema = {
name: 'Child',
primaryKey: 'id',
properties: {
'id' : 'string',
'name' : 'string'
}
};
const realmInstance = new RealmDB({
schema: [Passenger, Child],
});
export default realmInstance;
use.js
import realmInstance from "./realm";
export default class use {
static writeToRealm(){
realm.write(() => {
let passenger = realm.create('Passenger', {
'id' : "..."
'firstname' : "...",
'lastname' : "...",
"..."
})
}
static readPassengers(){
const passengers = realmInstance.objects('Passengers');
return passengers
}
}
Hope it's help :)
Related
this is error return in postman when i try to archive a record in my Sails backend.
UsageError: Invalid initial data for new records.\nDetails:\n Could not use one of the provided new records: Missing value for required attribute id. Expected a string, but instead, got: undefined\n [?] See https://sailsjs.com/support for help
Please somebody know what this error means? Thanks in advance.
Thanks for your response
My code:
- In controller:
try {
await Laboratory.archive({id: inputs.id});
} catch (error) {
console.log('Error-6 CORE-DELETE_LABORATORY:', error)
exits.failed(`Error-6 CORE-DELETE_LABORATORY: ${error}${inputs.id}`)}
In file config/models.js:
module.exports.models = {
migrate: 'alter',
fetchRecordsOnUpdate: true,
fetchRecordsOnCreate: true,
fetchRecordsOnCreateEach: true,
attributes: {
createdAt: { type: 'ref', columnType: 'datetime', autoCreatedAt: true, },
updatedAt: { type: 'ref', columnType: 'datetime', autoUpdatedAt: true, },
id: { type: 'string', columnName: '_id' },
},
dataEncryptionKeys: {
default: 'dRYQHBf8Zpza2vMS5BB3qcSiLspJP4BG37I2JkP2yYw='
},
cascadeOnDestroy: true
};
Laboratory model:
module.exports = {
attributes: {
type: {
type: 'string',
isIn: ['INSIDE', 'OUTSIDE'],
required: true,
},
raisonSocial: {
type: 'string',
required: true,
unique: true,
},
city: {
type: 'string'
},
address: {
type: 'string'
},
email: {
type: 'string'
},
neighborhood: {
type: 'string'
},
contacts: {
type: 'string'
},
logo: {
type: 'string'
},
lat: {
description: 'Latitude',
type: 'number'
},
long: {
description: 'Longitude',
type: 'number'
},
website: {
type: 'string',
defaultsTo: ''
},
subdomain: {
type: 'string',
unique: true,
required: true,
},
mobileMoney: {
type: 'string'
},
bank: {
type: 'string',
defaultsTo: ''
},
bankAccountID: {
type: 'string',
defaultsTo: ''
},
validated : {
type: 'boolean',
defaultsTo : false
},
f_establishment: {
model: 'establishment'
},
director: {
description: 'Chef of laboratory id',
type: 'json',
example: '{name, phone, role}',
required: true,
}
},
customToJSON () {
if (this.logo) {
this.logo = `${process.env.BASE_URL}/avatar/${this.logo}`
}
return this
}
};
Thanks.
Sails throws UsageError when we use a db method in an incorrect way. To be more precise, this is what Sails has in its documentation.
When an error has name: 'UsageError', this indicates that a Waterline
method was used incorrectly, or executed with invalid options (for
example, attempting to create a new record that would violate one of
your model's high-level validation rules.)
https://sailsjs.com/documentation/concepts/models-and-orm/errors#?usage-errors
To give you a simple example, if you have a db query with limit parameter and you start passing string values for that parameter, Sails with start throwing UsageError.
In your case, things should be self explanatory from the error detail itself. Your code flow is getting undefined for inputs.id when it tries to run Laboratory.archive({id: inputs.id}) but id is expected to be a string if you see config/models.js.
Just do a basic debugging to see why inputs.id is coming as undefined and solve that issue, and you should be good to go.
I have two entities, User and Role both with manyToMany association to each other.
Then I have a grid displaying the list of users and on the rightside a form with user details including a tagfield which will show and allow select roles for the user.
If the binding for the tagfield is set as
bind: {
store: '{roles}',
value: '{mainGrid.selection.roles}'
}
then it don't show the roles that the user already has and throws:
"Uncaught TypeError: parentData[association.setterName] is not a function"
when one tries to set the user roles
So I've also tried to bind the tagfield value to a formula like
bind: {
store: '{roles}',
value: '{userRoles}'
}
and the tagfield shows the roles of the selected user but I don't know how to set the selected roles back to the user entity.
My models are:
Ext.define('App.model.security.User', {
extend: 'App.model.Base',
entityName: 'User',
fields: [
{ name: 'id' },
{ name: 'email'},
{ name: 'name'},
{ name: 'enabled', type: 'bool'}
],
manyToMany: {
UserRoles: {
type: 'Role',
role: 'roles',
field: 'id',
right: {
field: 'id',
role: 'users'
}
}
}
});
and
Ext.define('App.model.security.Role', {
extend: 'App.model.Base',
entityName: 'Role',
fields: [
{ name: 'id' },
{ name: 'name'},
{ name: 'enabled', type: 'bool'}
],
manyToMany: {
RoleUsers: {
type: 'User',
role: 'users',
field: 'id',
right: {
field: 'id',
role: 'roles'
}
}
}
});
the tagfield definition:
xtype: 'tagfield',
fieldLabel: 'Roles',
displayField: 'name',
valueField: 'id',
stacked: true,
multiSelect: true,
filterPickList: true,
queryMode: 'local',
publishes: 'value',
bind: {
store: '{roles}',
value: '{userRoles}'
}
and the ViewModel:
Ext.define('App.view.security.user.UsersModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.users',
stores: {
users: {
model: 'App.model.security.User',
pageSize: 15,
autoLoad: true,
session: true
},
roles: {
model: 'App.model.security.Role',
autoLoad: true,
session: true
}
},
formulas: {
userRoles: {
bind: {
bindTo: '{mainGrid.selection.roles.data.items}',
deep: true
},
get: function(value){
return value;
},
set: function(value){
}
}
}
});
This is my very first project with Ext so maybe I'm missing some configuration at the model associations, I don't know.
I've googled a lot but lack information about the linked tagfield.
Any help will be gratefully appreciated.
Well I ended up using the formula by completing the missing code of the setter like this:
set: function(values){
//Delete the roles that were not established
var del = [], noadd = [];
var roles = this.get('mainGrid').selection.roles();
roles.each(function(record){
if (values.indexOf(record.get('id')) == -1) {
del.push(record);
}
else {
noadd.push(record.get('id'));
}
});
del.forEach(function(record){
roles.remove(record);
});
//Add the roles that didn't exist
var store = this.getStore('roles');
var allRecords = store.getData().getSource() || store.getData();
allRecords.each(function(record){
if (values.indexOf(record.get('id')) != -1 && noadd.indexOf(record.get('id')) == -1) {
roles.add(record);
}
});
}
Those arrays that I'm using are there because:
(del) cannot loop and delete over the same collection that I'm looping
(noadd) if I try to add an existing record into the roles collection it won't be added twice but at save time the existing record strangely appears as a create, I think this is a BUG.
I'll leave this question open for some time so if you know a better way to solve this you can make your contribution.
Thanks!
I'm storing user input into MongoDB with Sails / Waterline and because the type of field is dependent on their setup I'm finding it difficult to figure out the best way to store the data.
The 'surveyField' model is like:
// SURVEY FORM FIELD DEFINITIONS
module.exports = {
attributes: {
name: {
type: 'string',
required: true
},
label: {
type: 'string',
required: true
},
constraints: {
type: 'string',
enum: ['none', 'unique', 'combo', 'same'],
required: true,
defaultsTo: 'none'
},
isRequired: {
type: 'boolean',
required: true,
defaultsTo: false
},
attributeType: {
type: 'string',
enum: ['boolean', 'text', 'localizedText', 'enum', 'localizedEnum', 'number', 'money', 'date', 'time', 'dateTime'],
required: true
}
}
}
The user will have added any number of these fields to their form and so their form will contain a reference to the types of fields they have chosen. When their form is built I know exactly how to handle/display each of the fields based on this information, but saving the info is proving to be somewhat difficult because that Model needs to assume a type for the value field.
The 'surveyData' model looks like:
module.exports = {
attributes: {
value: {
**type: 'string' // THIS IS WHERE THE ISSUE IS**
},
surveyFieldType: {
model: 'surveyFieldType',
required: true
},
survey: {
model: 'survey',
required: true
},
user: {
model: 'user',
required: true
}
}
}
The issue occurs when the value might be a string or it might be json... or any of the other 'standard data types.'
Any help on this would be greatly appreciated.
** EDIT **
I'll also need this value to be searchable as well.
Maybe change it a little. And deal with survery answer as more complex value than just a value. Change type to JSON & build custom validator.
attributes: {
value: {
type: 'json'
}
}
and make it lake that
{
surveyFieldType: something,
value: {
type: 'Array',
value: [1,2,3]
},
survey: survey,
user: user
}
You can search now by that, you have flattened types of all replies. Based on value.type you can create custom validation rules for json.
I have these models:
// Material.js
module.exports = {
attributes: {
name: {
type: 'string',
required: true
},
source_info: {
type: 'string',
required: true
},
category: { model: 'category_mat' }
}
};
and:
// Category_Mat.js
module.exports = {
attributes: {
name: {
type: 'string',
required: true
},
material:{
collection: 'material',
via: 'category'
}
},
};
but when I run the app I get this error:
/usr/local/lib/node_modules/sails/node_modules/waterline/node_modules/waterline-schema/lib/waterline-schema/foreignKeys.js:82
throw new Error('Trying to access a collection ' + collection + ' that is
^
Error: Trying to access a collection category_mat that is not defined.
at ForeignKeys.findPrimaryKey (/usr/local/lib/node_modules/sails/node_modules/waterline/node_modules/waterline-schema/lib/waterline-schema/foreignKeys.js:82:11)
at ForeignKeys.replaceKeys (/usr/local/lib/node_modules/sails/node_modules/waterline/node_modules/waterline-schema/lib/waterline-schema/foreignKeys.js:53:27)
at new ForeignKeys (/usr/local/lib/node_modules/sails/node_modules/waterline/node_modules/waterline-schema/lib/waterline-schema/foreignKeys.js:30:10)
at new module.exports (/usr/local/lib/node_modules/sails/node_modules/waterline/node_modules/waterline-schema/lib/waterline-schema.js:30:17)
at Waterline.initialize (/usr/local/lib/node_modules/sails/node_modules/waterline/lib/waterline.js:106:17)
at buildORM (/usr/local/lib/node_modules/sails/lib/hooks/orm/build-orm.js:48:15)
at Array.async.auto.instantiatedCollections [as 1] (/usr/local/lib/node_modules/sails/lib/hooks/orm/index.js:191:11)
at listener (/usr/local/lib/node_modules/sails/node_modules/async/lib/async.js:465:46)
at /usr/local/lib/node_modules/sails/node_modules/async/lib/async.js:419:17
at Array.forEach (native)
I used this documentation as reference:
http://sailsjs.org/#/documentation/concepts/ORM/Associations/OnetoMany.html
so I don't know what I'm missing or if there is a configuration that I have to do... any help?
Maybe it is because "category-mat" used on Material.js is not defined anywhere... try
// Category_Mat.js
module.exports = {
identity: 'category_mat',
attributes: {
name: {
type: 'string',
required: true
},
material:{
collection: 'material',
via: 'category'
}
},
};
If this works the only side effect is that even if you have config/globals.js/models set to "true", you won't be able to access the model in the controllers by using "Category_Mat". You will either have to use "sails.models.category_mat" or just "category_mat".
This model gives me the effect I want at the expense of duplicated data and general uglyness:
//Example
var Example = {
attributes: {
foo: {
type: 'string',
required: true
},
bar: {
type: 'string',
required: true,
},
baz: {
type: 'integer',
required: true,
min: 1
},
foobar: {
type: 'string',
unique: true
}
},
beforeValidation : function(values,cb) {
values.foobar = values.foo+values.bar;
cb();
}
};
module.exports = Example;
Is there a better strategy for creating a composite unique key?
There's no way to do this directly in sails see https://github.com/balderdashy/waterline/issues/221. The best solution is to do this directly in the db you plan to use.