I have a realtion like this:
in my resolver I am fetching the enteties like this:
users: async () => {
const users = await db.user.findAll({
include: [
{
model: db.userroles,
include: [
{
model: db.roles,
attributes: ['Name'],
},
],
},
],
});
I log what I get from the db:
console.log('users are', users[0].dataValues.userroles[0].dataValues.role.Name); // logs "users are developer"
Which shows me that the correct roles are fetched.
My graphql schema:
type user {
Id: ID!
Email: String
RoleId: Int!
Password: String
ChangedPassword: Boolean
WeddingId: Int!
AttendantId: Int
role: [roles!]
}
type roles {
Id: ID!
Name: String!
}
In the playground I am sending this:
{users
{role
{Name}}
}
result:
"data": {
"users": [
{
"role": null
}
]
}
}
When I log the entire user object that I get back from the db:
users are userroles {
dataValues:
{ UserId: 1,
RoleId: 1,
role:
roles {
dataValues: [Object],
_previousDataValues: [Object],
_changed: {},
_modelOptions: [Object],
_options: [Object],
isNewRecord: false } },
_previousDataValues:
{ UserId: 1,
RoleId: 1,
role:
roles {
dataValues: [Object],
_previousDataValues: [Object],
_changed: {},
_modelOptions: [Object],
_options: [Object],
isNewRecord: false } },
_changed: {},
_modelOptions:
{ timestamps: false,
validate: {},
freezeTableName: true,
underscored: false,
paranoid: false,
rejectOnEmpty: false,
whereCollection: null,
schema: null,
schemaDelimiter: '',
defaultScope: {},
scopes: {},
indexes: [],
name: { plural: 'userroles', singular: 'userrole' },
omitNull: false,
tableName: 'userroles',
sequelize:
Sequelize {
options: [Object],
config: [Object],
dialect: [MysqlDialect],
queryInterface: [QueryInterface],
models: [Object],
modelManager: [ModelManager],
connectionManager: [ConnectionManager],
importCache: [Object] },
hooks: {} },
_options:
{ isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
include: [ [Object] ],
includeNames: [ 'role' ],
includeMap: { role: [Object] },
includeValidated: true,
raw: true,
attributes: undefined },
isNewRecord: false,
role:
roles {
dataValues: { Name: 'Developer' },
_previousDataValues: { Name: 'Developer' },
_changed: {},
_modelOptions:
{ timestamps: false,
validate: {},
freezeTableName: true,
underscored: false,
paranoid: false,
rejectOnEmpty: false,
whereCollection: null,
schema: null,
schemaDelimiter: '',
defaultScope: {},
scopes: {},
indexes: [],
name: [Object],
omitNull: false,
tableName: 'roles',
sequelize: [Sequelize],
hooks: {} },
_options:
{ isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
include: undefined,
includeNames: undefined,
includeMap: undefined,
includeValidated: true,
raw: true,
attributes: [Array] },
isNewRecord: false } }
I am getting the roles I just can't figure out how to present them?
I think that the issue is in my resolver that I am missing yet another set of includes but I cant figure out how to write it.
user and roles have a many-to-many relationship with userRoles as the junction table. If you have not already, should should define this relationship on user:
user.belongsToMany(roles, { through: userRoles })
This will let you include roles directly:
const users = await db.user.findAll({
include: [
db.roles,
],
});
After posting I noticed some issues in my schema.
I changed my schema to:
type roles {
Id: ID!
Name: String!
}
type userroles {
RoleId: ID!
UserId: ID!
role: roles
}
type user {
Id: ID!
Email: String
RoleId: Int!
Password: String
ChangedPassword: Boolean
WeddingId: Int!
AttendantId: Int
userroles: [userroles!]
}
playground:
{users
{userroles
{role
{Name}}}
}
result:
"data": {
"users": [
{
"userroles": [
{
"role": {
"Name": "Developer"
}
}
]
}
]
}
}
The answer stared me right in the face but I was focused on the code in the resolver.
Leaving this question in case someone has another way of doing this.
Related
I am running a Mongo query from the Order database which aims to fetch the orders of a particular user by using his email. This is done using an API, but I am getting the complete object with some unnecessary details.
Code
I have written the following API in nextJS name myorders:
import Order from "../../models/Order";
import connectDB from "../../middleware/mongoose";
import jsonwebtoken from "jsonwebtoken";
const handler = async(req, res) => {
const token = req.body.token;
const data = jsonwebtoken.verify(token,process.env.JWT_SECRET);
console.log(data)
let mere_orders = Order.find({email: data.email})
console.log("mereorders12 = ", mere_orders)
res.status(200).json({mere_orders});
}
export default connectDB(handler);
And console.log("mereorders12 = ", mere_orders) gives me this:
mereorders12 = Query {
_mongooseOptions: {},
_transforms: [],
_hooks: Kareem { _pres: Map(0) {}, _posts: Map(0) {} },
_executionStack: null,
mongooseCollection: Collection {
collection: Collection { s: [Object] },
Promise: [Function: Promise],
modelName: 'Order',
_closed: false,
opts: {
autoIndex: true,
autoCreate: true,
schemaUserProvidedOptions: [Object],
capped: false,
Promise: [Function: Promise],
'$wasForceClosed': undefined
},
name: 'orders',
collectionName: 'orders',
conn: NativeConnection {
base: [Mongoose],
collections: [Object],
models: [Object],
config: {},
replica: false,
options: null,
otherDbs: [],
relatedDbs: {},
states: [Object: null prototype],
_readyState: 1,
_closeCalled: undefined,
_hasOpened: true,
plugins: [],
id: 0,
_queue: [],
_listening: false,
_connectionString: 'mongodb://localhost:27017/chesswear',
_connectionOptions: [Object],
client: [MongoClient],
'$initialConnection': [Promise],
db: [Db],
host: 'localhost',
port: 27017,
name: 'chesswear'
},
queue: [],
buffer: false,
emitter: EventEmitter {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
[Symbol(kCapture)]: false
}
},
model: Model { Order },
schema: Schema {
obj: {
email: [Object],
orderId: [Object],
paymentInfo: [Object],
products: [Object],
address: [Object],
subtotal: [Object],
status: [Object]
},
paths: {
email: [SchemaString],
orderId: [SchemaString],
paymentInfo: [SchemaString],
products: [Mixed],
address: [SchemaString],
subtotal: [SchemaNumber],
status: [SchemaString],
_id: [ObjectId],
updatedAt: [SchemaDate],
createdAt: [SchemaDate],
__v: [SchemaNumber]
},
aliases: {},
subpaths: {},
virtuals: { id: [VirtualType] },
singleNestedPaths: {},
nested: {},
inherits: {},
callQueue: [],
_indexes: [],
methods: { initializeTimestamps: [Function (anonymous)] },
methodOptions: {},
statics: {},
tree: {
email: [Object],
orderId: [Object],
paymentInfo: [Object],
products: [Object],
address: [Object],
subtotal: [Object],
status: [Object],
_id: [Object],
updatedAt: [Function: Date],
createdAt: [Object],
__v: [Function: Number],
id: [VirtualType]
},
query: {},
childSchemas: [],
plugins: [ [Object], [Object], [Object], [Object], [Object] ],
'$id': 1,
mapPaths: [],
s: { hooks: [Kareem] },
_userProvidedOptions: { timestamps: true },
options: {
timestamps: true,
typeKey: 'type',
id: true,
_id: true,
validateBeforeSave: true,
read: null,
shardKey: null,
discriminatorKey: '__t',
autoIndex: null,
minimize: true,
optimisticConcurrency: false,
versionKey: '__v',
capped: false,
bufferCommands: true,
strictQuery: true,
strict: true,
pluralization: true
},
'$timestamps': { createdAt: 'createdAt', updatedAt: 'updatedAt' },
'$globalPluginsApplied': true,
_requiredpaths: [ 'status', 'subtotal', 'address', 'products', 'orderId', 'email' ]
},
op: 'find',
options: {},
_conditions: { email: 'mohit6#test.com' },
_fields: undefined,
_update: undefined,
_path: undefined,
_distinct: undefined,
_collection: NodeCollection {
collection: Collection {
collection: [Collection],
Promise: [Function: Promise],
modelName: 'Order',
_closed: false,
opts: [Object],
name: 'orders',
collectionName: 'orders',
conn: [NativeConnection],
queue: [],
buffer: false,
emitter: [EventEmitter]
},
collectionName: 'orders'
},
_traceFunction: undefined,
'$useProjection': true
}
But I should return order like this:
{
orders: [
{
"_id":"62693ae3f7fd0b7d87c8eb9c"},
"email":"mohit3#test.com",
"orderId":"1389629752594",
"paymentInfo":"No payment info",
"products":{...},
"address":"adasdklfasflka",
"subtotal":4,
"status":"Paid",
"createdAt":{"$date":"2022-04-27T12:45:23.352Z"},
"updatedAt":{"$date":"2022-04-27T12:45:23.352Z"},"__v":0
},
{
"_id":"62693ae3f7fd0b7d87c8eb9c"},
"email":"mohit3#test.com",
"orderId":"1389629752594",
"paymentInfo":"No payment info",
"products":{...},
"address":"adasdklfasflka",
"subtotal":14,
"status":"Paid",
"createdAt":{"$date":"2022-04-27T12:45:23.352Z"},
"updatedAt":{"$date":"2022-04-27T12:45:23.352Z"},"__v":0
}
]
}
Additionally this is the model schema of Order
const mongoose = require("mongoose");
const OrderSchema = new mongoose.Schema(
{
email: { type: String, required: true },
orderId: { type: String, required: true },
paymentInfo: { type: String, default: "No payment info" },
products: { type: Object, required: true },
address: { type: String, required: true },
subtotal: { type: Number, required: true },
status: { type: String, required: true, default: "Pending" },
},
{ timestamps: true }
);
export default mongoose.models.Order || mongoose.model("Order", OrderSchema);
Please help.
From Model.find(), it returns Query object.
Following the example, you need to execute the query asynchronously.
let mere_orders = await Order.find({email: data.email}).exec();
Or
let mere_orders = await Order.find({email: data.email});
As you are trying to return JSON as:
{
orders: [...]
}
You should return the response as below:
res.status(200).json({ orders: mere_orders });
When parsing I get this answer:
{
data: {
type: 'match',
id: 'ae825686-8a74-4363-a1d1-402d5a4207d5',
attributes: {
createdAt: '2018-11-20T17:06:52Z',
titleId: 'bluehole-pubg',
shardId: 'pc-ru',
tags: null,
seasonState: 'progress',
duration: 1823,
stats: null,
gameMode: 'squad-fpp'
},
},
included: [
{
type: 'participant',
id: '0b1b8f78-bb3e-4c0a-9955-9fdf8e33e5b4',
attributes: [Object]
},
{
type: 'participant',
id: '85e74b88-125b-4529-8c3f-fd76bd43b9aa',
attributes: [Object]
},
{
type: 'roster',
id: '6db70dce-b056-4bed-8cc4-6521b83bea50',
attributes: [Object],
relationships: [Object]
},
{
type: 'roster',
id: 'a35db9ae-e559-4474-b922-784e3221f484',
attributes: [Object],
relationships: [Object]
}
]
}
I need to get data with inculded type:'roster', and object contents attributes, relationships. How can I do it? I tried extracting array of data console.log(included [0]); I get data from type:'participant'. Tried so console.log (included [{type: 'roster', relationship}]); In response, I get the message undefined Please tell me how to get the necessary data.
Using Array.prototype.filter()
const response = {
data: {
type: 'match',
id: 'ae825686-8a74-4363-a1d1-402d5a4207d5',
attributes: {
createdAt: '2018-11-20T17:06:52Z',
titleId: 'bluehole-pubg',
shardId: 'pc-ru',
tags: null,
seasonState: 'progress',
duration: 1823,
stats: null,
gameMode: 'squad-fpp'
},
},
included: [
{
type: 'participant',
id: '0b1b8f78-bb3e-4c0a-9955-9fdf8e33e5b4',
attributes: [Object]
},
{
type: 'participant',
id: '85e74b88-125b-4529-8c3f-fd76bd43b9aa',
attributes: [Object]
},
{
type: 'roster',
id: '6db70dce-b056-4bed-8cc4-6521b83bea50',
attributes: [Object],
relationships: [Object]
},
{
type: 'roster',
id: 'a35db9ae-e559-4474-b922-784e3221f484',
attributes: [Object],
relationships: [Object]
}
]
}
const arrayWithRoster = response.included.filter(item => item.type === 'roster');
console.log(arrayWithRoster);
I would create two arrays and push individually, like this:
let json = {
data: {
type: 'match',
id: 'ae825686-8a74-4363-a1d1-402d5a4207d5',
attributes: {
createdAt: '2018-11-20T17:06:52Z',
titleId: 'bluehole-pubg',
shardId: 'pc-ru',
tags: null,
seasonState: 'progress',
duration: 1823,
stats: null,
gameMode: 'squad-fpp'
},
},
included: [
{
type: 'participant',
id: '0b1b8f78-bb3e-4c0a-9955-9fdf8e33e5b4',
attributes: [Object]
},
{
type: 'participant',
id: '85e74b88-125b-4529-8c3f-fd76bd43b9aa',
attributes: [Object]
},
{
type: 'roster',
id: '6db70dce-b056-4bed-8cc4-6521b83bea50',
attributes: [Object],
relationships: [Object]
},
{
type: 'roster',
id: 'a35db9ae-e559-4474-b922-784e3221f484',
attributes: [Object],
relationships: [Object]
}
]
}
let attributes = [];
let relationships = [];
let dataIneed = json.included.forEach(element => {
if(element.type === 'roster'){
attributes.push(element.attributes);
relationships.push(element.relationships);
}
})
So i have this following object in Javascript, and I am interested in only id: '410467873518256138', name: 'element1'
How can i extract this information from the object?
I tried storing it in object and doing object.id or object.name but it prints nothing.
'410467873518256138' => Emoji {
guild:
Guild {
members: [Object],
channels: [Object],
roles: [Object],
presences: [Object],
available: true,
id: '410467289767346186',
name: 'emoji_set4',
icon: null,
splash: null,
region: 'singapore',
memberCount: 2,
large: false,
features: [],
applicationID: null,
afkTimeout: 300,
afkChannelID: null,
systemChannelID: '410467289767346188',
embedEnabled: undefined,
verificationLevel: 0,
explicitContentFilter: 0,
joinedTimestamp: 1517933748730,
ownerID: '352458321456005123',
_rawVoiceStates: Collection {},
emojis: [Object] },
id: '410467873518256138',
name: 'element1',
requiresColons: true,
managed: false,
animated: false,
_roles: [] },
Also kindly explain what this syntax is '410467873518256138' => Emoji {, cause generally we write variable = {} to define an object.
I am experiencing an error using Sequelize and cannot figure out what the problem is.
I am creating a new record but after the record gets created it returns the results and then catches an exception and says the value is undefined. The record gets created but returns an error. I'm not sure why this is happening.
Here is my sql table
user_registration = conn.sequelize.define('user_registration',{
idUserRegistration:{
type: Sequelize.INTEGER(11).UNSIGNED,
primaryKey: true,
autoIncrement:true
},
email:{
type: Sequelize.STRING
},
firstName:{
type: Sequelize.STRING
},
lastName:{
type: Sequelize.STRING
},
guid:{
type: Sequelize.UUID,
defaultValue: Sequelize.UUIDV1
},
createDate:{
type: Sequelize.DATE, defaultValue: Sequelize.NOW
}
},{
freezeTableName: true
}
)
Here is the script for executing the statement
var
conn = require('../../mysql/mysqlConn')
,sequelize = require('sequelize')
,mysql = require('mysql')
,userRegistration = require('../../mysql/tables').user_registration
var createAccount = function(user,callback){
console.log('create user:',user.email)
var results = {}
try{
userRegistration.create({
email: user.email,
firstName: user.firstName,
lastName: user.lastName
})
.then(function(userRes){
console.log('userRegistration Results:',userRes)
results.error = false
results.results = userRes
callback(results)
})
.catch(function(err){
console.log('Caught error in createRegistration!')
console.log(err)
results.error = true
results.results = err
callback(results)
})
}catch(e){
console.log('EXCEPTION: error in createRegistration')
console.log(e)
results.error = true
results.results = 'Error occurred creating user registration:',e
callback(results)
}
}
exports.createAccount = createAccount
And here is the results with error that was encountered
create user: jsmith#me.com
Executing (default): INSERT INTO `user_registration` (`idUserRegistration`,`email`,`firstName`,`lastName`,`guid`,`create
Date`) VALUES (DEFAULT,'jsmith#me.com','John','Smith','a6193d70-198b-11e7-b0f0-93c15705c5db','2017-04-04 23:08:43');
userRegistration Results: Instance {
dataValues:
{ guid: 'a6193d70-198b-11e7-b0f0-93c15705c5db',
createDate: 2017-04-04T23:08:43.000Z,
idUserRegistration: 10,
email: 'jsmith#me.com',
firstName: 'John',
lastName: 'Smith' },
_previousDataValues:
{ email: 'jsmith#me.com',
firstName: 'John',
lastName: 'Smith',
idUserRegistration: 10,
guid: 'a6193d70-198b-11e7-b0f0-93c15705c5db',
createDate: 2017-04-04T23:08:43.000Z },
_changed:
{ email: false,
firstName: false,
lastName: false,
idUserRegistration: false,
guid: false,
createDate: false },
'$modelOptions':
{ timestamps: false,
instanceMethods: {},
classMethods: {},
validate: {},
freezeTableName: true,
underscored: false,
underscoredAll: false,
paranoid: false,
rejectOnEmpty: false,
whereCollection: { email: 'jsmith#me.com' },
schema: null,
schemaDelimiter: '',
defaultScope: {},
scopes: [],
hooks: {},
indexes: [],
name: { plural: 'user_registrations', singular: 'user_registration' },
omitNul: false,
sequelize:
Sequelize {
options: [Object],
config: [Object],
dialect: [Object],
models: [Object],
modelManager: [Object],
connectionManager: [Object],
importCache: {},
test: [Object],
queryInterface: [Object] },
uniqueKeys: {},
hasPrimaryKeys: true },
'$options':
{ isNewRecord: true,
'$schema': null,
'$schemaDelimiter': '',
attributes: undefined,
include: undefined,
raw: undefined,
silent: undefined },
hasPrimaryKeys: true,
__eagerlyLoadedAssociations: [],
isNewRecord: false }
Caught error in createRegistration!
TypeError: Cannot read property 'email' of undefined
Any ideas?
thanks in advance for your time and answers:
I've been trying to do something that "should" be easy but it's being me crazy.
the objective is to asign the result of a function to a variable that i can use later on a POST to send information to my MongoDB.
I've a model with a document as:
{ "__v" : 0, "_id" : ObjectId("54ad1aa637ce5c566c13d18f"), "num" : 9 }
What i want is to capture this number "num" : 9 to a variable. I created a function that query the mongodb through the model.
function getNum(){
var Num = require('./models/num.js');
var callback = function(){
return function(err, data) {
if(err) {
console.log("error found: " + err);
}
console.log("the number is: " + data.num);
}
};
return Num.findOne({}, callback());
};
then just to test i assign that function to a variable and try to console.log it just to test if the result is fine.
// =====================================
// TESTING ==============================
// =====================================
app.get('/testing',function(req, res, next){
var a = getNum();
console.log(a);
});
My output is:
{ _mongooseOptions: {},
mongooseCollection:
{ collection:
{ db: [Object],
collectionName: 'num',
internalHint: null,
opts: {},
slaveOk: false,
serializeFunctions: false,
raw: false,
pkFactory: [Object],
serverCapabilities: undefined },
opts: { bufferCommands: true, capped: false },
name: 'num',
conn:
{ base: [Object],
collections: [Object],
models: [Object],
config: [Object],
replica: false,
hosts: null,
host: 'localhost',
port: 27017,
user: undefined,
pass: undefined,
name: 'project',
options: [Object],
otherDbs: [],
_readyState: 1,
_closeCalled: false,
_hasOpened: true,
_listening: true,
_events: {},
db: [Object] },
queue: [],
buffer: false },
model:
{ [Function: model]
base:
{ connections: [Object],
plugins: [],
models: [Object],
modelSchemas: [Object],
options: [Object] },
modelName: 'Num',
model: [Function: model],
db:
{ base: [Object],
collections: [Object],
models: [Object],
config: [Object],
replica: false,
hosts: null,
host: 'localhost',
port: 27017,
user: undefined,
pass: undefined,
name: 'project',
options: [Object],
otherDbs: [],
_readyState: 1,
_closeCalled: false,
_hasOpened: true,
_listening: true,
_events: {},
db: [Object] },
discriminators: undefined,
schema:
{ paths: [Object],
subpaths: {},
virtuals: [Object],
nested: {},
inherits: {},
callQueue: [Object],
_indexes: [],
methods: {},
statics: {},
tree: [Object],
_requiredpaths: undefined,
discriminatorMapping: undefined,
_indexedpaths: undefined,
options: [Object],
_events: {} },
options: undefined,
collection:
{ collection: [Object],
opts: [Object],
name: 'num',
conn: [Object],
queue: [],
buffer: false } },
op: 'findOne',
options: {},
_conditions: {},
_fields: undefined,
_update: undefined,
_path: undefined,
_distinct: undefined,
_collection:
{ collection:
{ collection: [Object],
opts: [Object],
name: 'num',
conn: [Object],
queue: [],
buffer: false } },
_castError: null }
**the number is: 9**
This is one of the results i can get in other aproaches i get undefined.
Can anyone wonder what can i do to solve this?
Again thanks for your help.
You can't return the result of an asynchronous function like findOne, you need to use callbacks.
So it would need to be rewritten as something like:
function getNum(callback){
var Num = require('./models/num.js');
return Num.findOne({}, callback);
};
app.get('/testing',function(req, res, next){
getNum(function(err, a) {
console.log(a);
});
});