How to store Array of Objects in realm-js? - react-native

import Realm from 'realm';
class Cities extends Realm.Object {}
class Users extends Realm.Object {}
Cities.schema = {
name: 'Cities',
properties: {
'name': {
type: 'string'
},
'pincode': {
type: 'int'
}
}
};
Users.schema = {
name: 'Users',
primaryKey: 'id',
properties: {
'id': 'string',
'name': {
type: 'string'
},
'city': {
type: 'list',
objectType: 'Cities'
}
}
};
const schemaList = [Users, Cities];
const realmInstance = new Realm({schema: schemaList});
export default realmInstance;
// pushing a cityObj (that is already present in 'Cities') for a existing User:
onPress={() => this.addCity({name: 'Delhi', pincode: 110004})}
addCity = (cityObj) => {
realm.write(() => {
let user = realm.create('Users', {
'id': 'someUniqueID'
}, true);
user.city.push(cityObj);
});
let cities = realm.objects('Cities');
console.log('cities.length', cities.length);
}
though, trying to update a record in 'Users', The write transaction is writing a new record in Cities table as well creating duplicates. Why so?

Adding to a list will in general create a new object. But you can add a primary key to Cities, create/update the object first and finally push it to the list. Something like:
const Realm = require('realm');
const CitiesSchema = {
name: 'Cities',
primaryKey: 'pincode',
properties: {
'name': {
type: 'string'
},
'pincode': {
type: 'int'
}
}
};
const UsersSchema = {
name: 'Users',
primaryKey: 'id',
properties: {
'id': 'string',
'name': {
type: 'string'
},
'city': {
type: 'list',
objectType: 'Cities'
}
}
};
const schemaList = [UsersSchema, CitiesSchema];
const realm = new Realm({schema: schemaList});
addCity = (cityObj) => {
realm.write(() => {
let city = realm.create('Cities', cityObj, true);
let user = realm.create('Users', {
id: 'someUniqueID',
name: 'Foo Bar'
}, true);
user.city.push(city);
});
let cities = realm.objects('Cities');
console.log('cities.length', cities.length);
}
addCity({name: 'Delhi', pincode: 110004});
addCity({name: 'Delhi', pincode: 110004});

Related

Sequelize Count and Group Nested Include

I have got a few sql tables as
export default (sequelize, Sequelize) => {
return sequelize.define('teacher', {
tagline: {
type: Sequelize.TEXT,
},
modeOfPayment: {
type: Sequelize.STRING,
},
modeOfSession: {
type: Sequelize.STRING,
},
preferredTimeZones: {
type: Sequelize.STRING,
},
titleForSessions: {
type: Sequelize.STRING,
},
availableForWork: {
type: Sequelize.BOOLEAN,
},
});
};
export default (sequelize, Sequelize) => {
return sequelize.define('skill', {
name: {
type: Sequelize.STRING,
unique: true,
allowNull: false,
},
});
};
export default (sequelize, Sequelize) => {
return sequelize.define('category', {
name: {
type: Sequelize.STRING,
unique: true,
allowNull: false,
},
});
};
Here is the model relation between them
Teacher.belongsToMany(Skill, {
through: 'skill_teacher',
});
Skill.belongsToMany(Teacher, {
through: 'skill_teacher',
});
Category.hasMany(Skill);
Skill.belongsTo(Category);
Earlier I needed to query count of teachers in each skill, here's my controller for that
// #desc Get skill count for each skill
// #route GET /api/skills/count
// #access Public
const getSkillCount = asyncHandler(async (req, res) => {
try {
const skills = await Skill.findAll({
attributes: [
'id',
'name',
[sequelize.fn('count', sequelize.col('teachers.id')), 'teacherCount'],
],
include: [{ attributes: [], model: Teacher }],
group: ['skill.id'],
});
res.json(skills);
} catch (err) {
console.log(err.message);
res.status(500);
throw new Error(err.message);
}
});
Now, the skills are grouped in categories. So I wanna query a list of skills having their own teacher count grouped in their own categories, which category also having a skillCount column. I tried this but it is not giving my desired results
// #desc Get category and their skills counts
// #route GET /api/categories/skills/count
// #access Public
const getCategorySkillCounts = asyncHandler(async (req, res) => {
try {
const categories = await Category.findAll({
attributes: [
'id',
'name',
[sequelize.fn('count', sequelize.col('skills.id')), 'skillCount'],
],
include: {
model: Skill,
include: [{ model: Teacher }],
attributes: [
'id',
'name',
[sequelize.fn('count', sequelize.col('teachers.id')), 'teacherCount'],
],
group: ['skill.id'],
},
group: ['category.id'],
});
res.json(categories);
} catch (err) {
console.log(err.message);
res.status(500);
throw new Error(err.message);
}
});

XState.js How to send context to a machine?

I am new to XState.js.
I want to use a simple ID in my context. How do I update the context using machine.send()?
const fetchMachine = Machine(
{
id: 'test',
initial: 'init',
context: {
id: '',
},
states: {
init: {
on: {
LOGIN: 'fetch',
},
},
fetch: {
on: {
LOGOUT: 'init',
},
},
}
})
const machine = interpret(fetchMachine).start()
How do I pass an ID to the context?
This does NOT do the trick:
machine.send({ type: 'LOGIN', id })
You have to use the assign action to update the context. I've updated your example to the following:
import { Machine, assign } from 'xstate';
// Action to assign the context id
const assignId = assign({
id: (context, event) => event.id
});
export const testMachine = Machine(
{
id: 'test',
initial: 'init',
context: {
id: '',
},
states: {
init: {
on: {
LOGIN: {
target: 'fetch',
actions: [
assignId
]
}
},
},
fetch: {
on: {
LOGOUT: 'init',
},
},
}
},
{
actions: { assignId }
}
);
Now once you call the following:
import { testMachine } from './machines';
const testService = interpret(testMachine).start();
testService.send({type: 'LOGIN', id: 'test' });
//or testService.send('LOGIN', { id: 'test'});
the action assignId will assign data from the event to your context

How can I join two tables with REALM

I am new to REALM and I am trying to join two tables but I can't find information of sql query for realm (I am using React Native)
Tables are ChatRoom and Message. ChatRoom has multiple Messages. I would like to get all chatrooms with only one most lastest message for each chatroom.
ChatRoom.schema = {
name: 'fcm_chat_room',
primaryKey: 'chat_room_id',
properties: {
chat_room_id: 'string',
chat_room_name: {type: 'string', default: ''},
chat_room_date: 'date'
}
};
Message.schema = {
name: 'fcm_message',
primaryKey: 'message_id',
properties: {
message_id: 'string',
chat_room_id: 'string',
sender_id: 'string',
sender_reg_id: 'string',
message: 'string',
msg_date: 'date',
is_read: {type: 'bool', default: false}
}
};
try this example, it will help you to join table in realm database.
const CarSchema = {
name: 'Car',
properties: {
make: 'string',
model: 'string',
miles: {type: 'int', default: 0},
}
};
const PersonSchema = {
name: 'Person',
properties: {
name: 'string',
birthday: 'date',
cars: {type: 'list', objectType: 'Car'},
picture: {type: 'data', optional: true}, // optional property
}
};
// Initialize a Realm with Car and Person models
let realm = new Realm({schema: [CarSchema, PersonSchema]});
Combine React Native
const Realm = require('realm');
class extends Component {
render() {
let realm = new Realm({
schema: [{name: 'Dog', properties: {name: 'string'}}]
});
realm.write(() => {
realm.create('Dog', {name: 'Rex'});
});
return (
Count of Dogs in Realm: {realm.objects('Dog').length}
);
}
}

Transpiled GraphQL with Babel is throwing error "Cannot call class as function"

I am trying to get running GraphQL server. I have simple schema in GraphQL
import {
GraphQLObjectType,
GraphQLInt,
GraphQLString,
GraphQLList,
GraphQLSchema
} from 'graphql'
import db from './models'
const user = new GraphQLObjectType({
name: "user",
description: 'This represents a user',
fields: () => {
return {
id: {
type: GraphQLInt,
resolve(user) {
return user.id
}
},
firstName: {
type: GraphQLString,
resole(user) {
return user.firstName
}
},
lastName: {
type: GraphQLString,
resole(user) {
return user.lastName
}
},
email: {
type: GraphQLString,
resole(user) {
return user.email
}
},
createdAt: {
type: GraphQLString,
resole(user) {
return user.createdAt
}
},
updatedAt: {
type: GraphQLString,
resole(user) => {
return user.updatedAt
}
}
}
}
})
const Query = new GraphQLObjectType({
name: 'Query',
description: 'This is root Query',
fields: () => {
return {
users: {
type: GraphQLList(user),
args: {
id: {
type: GraphQLInt
},
email: {
type: GraphQLString
}
},
resolve(root, args) {
return db.user.findAll({where: args})
}
}
}
}
})
const Schema = new GraphQLSchema({
query: Query
})
export default Schema
I am transpile it with babel into ES5, but every time when I try run it with express
import GraphHTTP from 'express-graphql'
import Schema from './schema'
app.use('/grapql', GraphHTTP({
schema: Schema,
pretty: true,
graphiql: true
}))
I am getting this error
\node_modules\graphql\type\definition.js:41
function _classCallCheck(instance, Constructor) { if (!instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }                                                             
TypeError: Cannot call a class as a function
I check it again and again if i have some typing error but i didnt find enything.
instead of type: GraphQLList(user) use type: new GraphQLList(user)
GraphQLList is a class and you have to create it's instance and use, but you have called it as a function.
const Query = new GraphQLObjectType({
name: 'Query',
description: 'This is root Query',
fields: () => {
return {
users: {
type: new GraphQLList(user),
args: {
id: {
type: GraphQLInt
},
email: {
type: GraphQLString
}
},
resolve(root, args) {
return db.user.findAll({where: args})
}
}
}
}
})

Sequelize findAll where many to many criteria

I have 2 models User and Item with many to many relation, here is the definitions:
User = sequelize.define('User', {
name: {type: Sequelize.STRING}
})
Item = sequelize.define('Item', {
name: {
type: Sequelize.STRING,
allowNull: false
}
}
User.belongsToMany(models.Item, {
as: 'items',
through: 'UserItem'
})
Item.belongsToMany(models.User, {
as: 'owners',
through: 'UserItem'
})
And my request is :
Item.findAll({
include: [{
model: User,
through: {
where: {id: 2}
}
}]
}).then(items => {
log.debug(items)
}).catch(err => {
log.error(err)
})
Then I have : Error: User is not associated to Item!
I also try this :
Item.findAll({
where: {'owners.id': 2},
include: Item.assocations.owners
}).then(items => {
debug(items)
}).catch(err => {
log.error(err)
})
But now I have Error: SQLITE_ERROR: no such column: Item.owners.id
Any ideas ?
Here is my working solution :
'use strict'
const Sequelize = require('Sequelize')
const sequelize = new Sequelize({
host: 'localhost',
dialect: 'sqlite',
// SQLite only
storage: 'database.sqlite'
})
const User = sequelize.define('user', {
name: {
type: Sequelize.STRING
}
}, {
freezeTableName: true // Model tableName will be the same as the model name
})
const Item = sequelize.define('item', {
name: {
type: Sequelize.STRING
}
}, {
freezeTableName: true // Model tableName will be the same as the model name
})
const UserItem = sequelize.define('useritem', {})
User.belongsToMany(Item, {
as: 'items',
through: 'useritem'
})
Item.belongsToMany(User, {
as: 'owners',
through: 'useritem'
})
Promise.all([
User.sync({force: true}),
Item.sync({force: true}),
UserItem.sync({force: true})])
.then(() => {
return Promise.all([
User.create({name: 'test'}),
User.create({name: 'admin'}),
Item.create({name: 'item1'}),
Item.create({name: 'item2'})])
.then(results => {
return results[2].addOwner(results[0])
}).then(() => {
return Item.findAll({
include: {model: User, as: 'owners', where:{
'id': 1
}}
}).then(items => {
console.log(items)
})
})
}).catch(err => console.log(err))
as need to be on include clause and where should be added on include too