How to get data when parse Node.js - javascript

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);
}
})

Related

MongoDB find() giving wrong object?

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 });

TypeORM - One-To-Many relationship defined in EntitySchema

I'm using TypeORM with JS and it's docs are super minimal, so I couldn't find the solution for my question over there.
I want to create a one-to-many bi-directional relationship and can't get over the following exception:
TypeORMError: Entity metadata for Team#groups was not found. Check if you specified a correct entity object and if it's connected in the connection options.
Thats the definition of the two entities (one team might have multiple groups):
module.exports = new EntitySchema({
name: 'Team',
tableName: 'team',
columns: {
id: {
primary: true,
type: 'uuid',
generated: true,
},
name: {
type: 'varchar',
},
},
relations: {
groups: {
target: 'TeamGroups',
type: 'one-to-many',
inverseSide: 'team_id',
},
},
})
module.exports = new EntitySchema({
name: 'TeamsGroups',
tableName: 'team_group',
columns: {
team_id: {
primary: true,
type: 'uuid',
},
group_id: {
primary: true,
type: 'uuid',
},
},
relations: {
team_id: {
target: 'Team',
type: 'many-to-one',
joinColumn: true,
},
},
})
What am I missing?
I can't test but I'm fairly sure it's this, looking at the error & docs:
module.exports = new EntitySchema({
name: 'Team',
tableName: 'team',
columns: {
id: {
primary: true,
type: 'uuid',
generated: true,
},
name: {
type: 'varchar',
},
},
relations: {
TeamGroups: {
target: 'TeamGroups',
type: 'one-to-many',
inverseSide: 'team_id',
},
},
})
module.exports = new EntitySchema({
name: 'TeamsGroups',
tableName: 'team_group',
columns: {
team_id: {
primary: true,
type: 'uuid',
},
group_id: {
primary: true,
type: 'uuid',
},
},
relations: {
Team: {
target: 'Team',
type: 'many-to-one',
joinColumn: true,
},
},
})

How does one access properties within a nested array and object data structure?

How can I access properties within a nested array and object data structure.
I wish to access the data within the sub property of the object. However as you can see the sub property values do feature objects as well. So here is my code where I am using loop to access the property within this objects which would look something like this as shown below:
[{
updateTime: '2021-08-01T10:31:12.997Z',
state: 'PUBLISHED',
description: '[Assignment Link]',
creationTime: '2021-08-01T10:00:32.502Z',
creatorUserId: '100720723991781953762',
maxPoints: 100,
assigneeMode: 'ALL_STUDENTS',
title: 'Chapter 10 - Challenge - Sounds',
topicId: '371133499749',
dueTime: {
hours: 12,
minutes: 29
},
courseId: '359355912330',
dueDate: {
year: 2021,
day: 2,
month: 8
},
submissionModificationMode: 'MODIFIABLE_UNTIL_TURNED_IN',
alternateLink: 'Links',
id: '375299410585',
workType: 'ASSIGNMENT',
sub: {
'101319245169270376329': [Object],
'113602874081893916075': [Object],
'109482297400381284245': [Object],
'116018616608318973354': [Object],
'113664444807142890993': [Object],
'114971581068847820301': [Object],
'102115961232295542434': [Object],
'101379903617328602973': [Object],
'110645572827894944226': [Object],
'116196654365604694016': [Object],
'111060187005391455662': [Object],
'109231821126887264833': [Object],
'111638802824371384480': [Object],
'107268429707932588376': [Object],
'113020667154770187233': [Object],
'102653891403954041925': [Object],
'105324491423107091552': [Object],
'101716831976886159513': [Object],
'100197750836727383685': [Object],
'109019166529420617094': [Object],
'115372484470281534681': [Object],
'114443976641819242498': [Object]
}
}]
I am trying to access this late and other properties of the object here. Here I am showing you this example by using the following code.
console.log(courseWork[0].sub);
However when I try to access its sub properties like late or state I am not getting them and I get a undefined in my console like this:
console.log(courseWork[0].sub.late);
{
alternateLink: 'Links',
courseWorkType: 'ASSIGNMENT',
courseId: '359355912330',
assignmentSubmission: {},
userId: '101319245169270376329',
courseWorkId: '375299410585',
id: 'Cg0I9eKUzyYQmZXajPYK',
submissionHistory: [Object],
state: 'CREATED',
late: true,
creationTime: '2021-08-01T10:31:45.071Z',
updateTime: '2021-08-01T10:31:45.036Z'
}
Now I am new at javascript and appscript and never dealt with such big data and objects. How can i access the data to this level.
Please consult documentations to Object.keys, Object.values and Object.entries ...
var obj = {
sub: {
'101319245169270376329': { late: true },
'113602874081893916075': { late: true },
'109482297400381284245': { late: false },
'116018616608318973354': { late: true },
'113664444807142890993': { late: true },
'114971581068847820301': { late: false },
'102115961232295542434': { late: true },
'101379903617328602973': { late: false },
}
};
Object
.entries(obj.sub)
.forEach(([key, value]) =>
console.log(`'${ key }' ... late: ${ value.late }`)
);
Object
.values(obj.sub)
.forEach(item => console.log(`late: ${ item.late }`));
.as-console-wrapper { min-height: 100%!important; top: 0; }
var obj = {
updateTime: '2021-08-01T10:31:12.997Z',
state: 'PUBLISHED',
description: '[Assignment Link]',
creationTime: '2021-08-01T10:00:32.502Z',
creatorUserId: '100720723991781953762',
maxPoints: 100,
assigneeMode: 'ALL_STUDENTS',
title: 'Chapter 10 - Challenge - Sounds',
topicId: '371133499749',
dueTime: {
hours: 12,
minutes: 29
},
courseId: '359355912330',
dueDate: {
year: 2021,
day: 2,
month: 8
},
submissionModificationMode: 'MODIFIABLE_UNTIL_TURNED_IN',
alternateLink: 'Links',
id: '375299410585',
workType: 'ASSIGNMENT',
sub: {
'101319245169270376329': {
alternateLink: 'Links',
courseWorkType: 'ASSIGNMENT',
courseId: '359355912330',
assignmentSubmission: {},
userId: '101319245169270376329',
courseWorkId: '375299410585',
id: 'Cg0I9eKUzyYQmZXajPYK',
submissionHistory: {},
state: 'CREATED',
late: true,
creationTime: '2021-08-01T10:31:45.071Z',
updateTime: '2021-08-01T10:31:45.036Z'
},
'113602874081893916075': {},
'109482297400381284245': {},
'116018616608318973354': {},
'113664444807142890993': {},
'114971581068847820301': {},
'102115961232295542434': {},
'101379903617328602973': {},
'110645572827894944226': {},
'116196654365604694016': {},
'111060187005391455662': {},
'109231821126887264833': {},
'111638802824371384480': {},
'107268429707932588376': {},
'113020667154770187233': {},
'102653891403954041925': {},
'105324491423107091552': {},
'101716831976886159513': {},
'100197750836727383685': {},
'109019166529420617094': {},
'115372484470281534681': {},
'114443976641819242498': {}
}
};
console.log(obj.sub['101319245169270376329'].late); // output: true

How to get user-roles with sequelize?

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.

Mongoose populate virtuals - exclude localField and foreignField from the query results if foreignField is null or an empty array

I have a simple question.
In Mongoose I have two models. One is for Leagues and the other one is for Fixtures. Each league has a unique id, and each fixture is related to a league with it's key of league_id.
In the Leagues schema I have also defined a virtual called fixtures.
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const LeagueSchema = new Schema(
{
_id: { type: mongoose.Schema.Types.ObjectId, select: false, auto: true },
id: { type: Number, required: true, unique: true, index: true },
name: { type: String, required: true },
}
);
LeagueSchema.virtual('fixtures', {
ref: 'fixtures',
localField: 'id',
foreignField: 'league_id',
justOne: false,
});
const Leagues = mongoose.model('leagues', LeagueSchema);
const FixtureSchema = new Schema(
{
_id: { type: mongoose.Schema.Types.ObjectId, select: false },
match_id: { type: Number, required: true, index: true, unique: true },
league_id: { type: Number, required: true },
league_name: { type: String, required: true },
timestamp: { type: Number, required: true, index: true },
}
);
const Fixtures = mongoose.model('fixtures', FixtureSchema);
Here is the problem. The list of all leagues is very big and not all of them will always have fixtures that match the .populate() so I want to exclude them from my query.
For example, if I don't want any fixtures older than a given timestamp, I will do the following:
(async () => {
const target_time = 1568851200000;
const leagues = await Leagues
.find({})
.populate({ path: 'fixtures', match: { timestamp: { $gte: target_time } } })
.lean();
console.log(leagues);
})();
What this does is it filters out the fixtures by timestamp correctly, but it does not exclude Leagues without fixtures from the query.
Here is what this query returns:
Current result:
[
{
id: 2,
name: 'Champions League',
fixtures: []
},
{
id: 5,
name: 'Europa League',
fixtures: [
[Object],
[Object],
[Object],
[Object],
]
},
{
id: 8,
name: 'Premier League',
fixtures: []
}
];
And here is what I want to achieve:
Desired result:
[
{
id: 5,
name: 'Europa League',
fixtures: [
[Object],
[Object],
[Object],
[Object],
]
},
];
I am aware that I can do something like leagues.filter(item => item.fixtures.length > 0), but this query is going to be called tens of times each second, I'm afraid that running another filter after the query can lead to performance issues.
Any help or possible alternatives are appreciated.

Categories