values must be an object with value names as keys - node.js

I have created an enum type for my object
const MonthType = new GraphQLEnumType({
name: 'monthType',
value: {
JANUARY:{
value: "January"
},
FEBRUARY: {
value: 'February'
},
MARCH: {
value: 'March'
},
MAY: {
value: 'May'
},
JUNE: {
value: 'June'
},
JULY: {
value: 'July'
},
AUGUST: {
value: "August"
},
SEPTEMBER: {
value: 'September'
},
OCTOBER: {
value: 'October'
},
NOVEMEBER: {
value: 'November'
},
DECEMBER: {
value: 'December'
}
}
})
which I am using kind of like this in my Object type
const UserType = new GraphQLObjectType({
name: 'User', // Importance of Name here
fields: () => ({
id: {
type: GraphQLInt
},
userId: {
type: GraphQLInt
},
gradMonth: {
type: MonthType
},
Now, Whenever I start my express server, I am thrown the following error in my code
monthType values must be an object with value names as keys
What I intend to do? I want the user to select, pass the value of the month which should be one of these.
Can someone help me in figuring out why I am getting the following error?

Try replacing value by values at the begining :
const MonthType = new GraphQLEnumType({
name: 'monthType',
values: { // <=== here
//...

Related

how to put mongodb items in variables for discord bot?

This is the model:
Schema = mongoose.Schema;
module.exports = mongoose.model(
"Leveling",
new Schema({
guildID: {
type: String
},
guildName: {
type: String
},
roletoad: {
type: String,
default: "null"
},
roletoremove: {
type: String,
default: "null"
},
rolelevel: {
type: Number,
default: 0
},
})
);
This is the command to get all leveling roles in a specific guild:
if(args[0]==="list"){
const del = await Leveling.find({
guildID: message.guild.id,
},{
_id: 0,
roletoad: 1,
roletoremove: 1,
rolelevel:1
})
return await message.channel.send(del)
}
This is the output:
{
roletoad: '735106092308103278',
roletoremove: '731561814407774248',
rolelevel: 5
}
{
roletoad: '735598034385371167',
roletoremove: '744562691817078905',
rolelevel: 7
}
I want to know how to get each item(roletoad,roletoremove,rolelevel) in a specific variable.
It seems you're getting an array of objects form your db in the del variable, and each object in that array has the properties roletoad, roletoremove and rolelevel, which you want in separate variables.
For each object of your array, you can store these properties in variables by object destructuring. One approach is as follows:
//the data you'll get from the db
const del = [{
roletoad: '735106092308103278',
roletoremove: '731561814407774248',
rolelevel: 5
},
{
roletoad: '735598034385371167',
roletoremove: '744562691817078905',
rolelevel: 7
}]
for(const {
roletoad: yourRoleToAddVar,
roletoremove: yourRoleToRemoveVar,
rolelevel: yourRoleToLevelVar
} of del){
console.log(`Role to add: ${yourRoleToAddVar}`)
console.log(`Role to remove: ${yourRoleToRemoveVar}`)
console.log(`Role Level: ${yourRoleToLevelVar}`)
console.log(`---------------------------`)
//do what you want with these variables here
}
NOTE: This should go without saying but the scope of these variables will only be valid within this loop.

How to grab field value during a MongooseModel.bulkWrite operation?

Context:
I am trying to upsert in bulk an array of data, with an additional computed field: 'status'.
Status should be either :
- 'New' for newly inserted docs;
- 'Removed' for docs present in DB, but inexistent in incoming dataset;
- a percentage explaining the evolution for the field price, comparing the value in DB to the one in incoming dataset.
Implementations:
data.model.ts
import { Document, model, Model, models, Schema } from 'mongoose';
import { IPertinentData } from './site.model';
const dataSchema: Schema = new Schema({
sourceId: { type: String, required: true },
name: { type: String, required: true },
price: { type: Number, required: true },
reference: { type: String, required: true },
lastModified: { type: Date, required: true },
status: { type: Schema.Types.Mixed, required: true }
});
export interface IData extends IPertinentData, Document {}
export const Data: Model<IData> = models.Data || model<IData>('Data', dataSchema);
data.service.ts
import { Data, IPertinentData } from '../models';
export class DataService {
static async test() {
// await Data.deleteMany({});
const data = [
{
sourceId: 'Y',
reference: `y0`,
name: 'y0',
price: 30
},
{
sourceId: 'Y',
reference: 'y1',
name: 'y1',
price: 30
}
];
return Data.bulkWrite(
data.map(function(d) {
let status = '';
// #ts-ignore
console.log('price', this);
// #ts-ignore
if (!this.price) status = 'New';
// #ts-ignore
else if (this.price !== d.price) {
// #ts-ignore
status = (d.price - this.price) / this.price;
}
return {
updateOne: {
filter: { sourceId: d.sourceId, reference: d.reference },
update: {
$set: {
// Set percentage value when current price is greater/lower than new price
// Set status to nothing when new and current prices match
status,
name: d.name,
price: d.price
},
$currentDate: {
lastModified: true
}
},
upsert: true
}
};
}
)
);
}
}
... then in my backend controller, i just call it with some route :
try {
const results = await DataService.test();
return new HttpResponseOK(results);
} catch (error) {
return new HttpResponseInternalServerError(error);
}
Problem:
I've tried lot of implementation syntaxes, but all failed either because of type casting, and unsupported syntax like the $ symbol, and restrictions due to the aggregation...
I feel like the above solution might be closest to a working scenario but i'm missing a way to grab the value of the price field BEFORE the actual computation of status and the replacement with updated value.
Here the value of this is undefined while it is supposed to point to current document.
Questions:
Am i using correct Mongoose way for a bulk update ?
if yes, how to get the field value ?
Environment:
NodeJS 13.x
Mongoose 5.8.1
MongoDB 4.2.1
EUREKA !
Finally found a working syntax, pfeeeew...
...
return Data.bulkWrite(
data.map(d => ({
updateOne: {
filter: { sourceId: d.sourceId, reference: d.reference },
update: [
{
$set: {
lastModified: Date.now(),
name: d.name,
status: {
$switch: {
branches: [
// Set status to 'New' for newly inserted docs
{
case: { $eq: [{ $type: '$price' }, 'missing'] },
then: 'New'
},
// Set percentage value when current price is greater/lower than new price
{
case: { $ne: ['$price', d.price] },
then: {
$divide: [{ $subtract: [d.price, '$price'] }, '$price']
}
}
],
// Set status to nothing when new and current prices match
default: ''
}
}
}
},
{
$set: { price: d.price }
}
],
upsert: true
}
}))
);
...
Explanations:
Several problems were blocking me :
the '$field_value_to_check' instead of this.field with undefined 'this' ...
the syntax with $ symbol seems to work only within an aggregation update, using update: [] even if there is only one single $set inside ...
the first condition used for the inserted docs in the upsert process needs to check for the existence of the field price. Only the syntax with BSON $type worked...
Hope it helps other devs in same scenario.

How to save an array of objects into a mongoose db

I am trying to save a leader board made of objects nested in an array. I want to save it in my database, but I have not been able to create the right schema and I don't think I that is the best way to go.
When I run the code I get the error of:
"LeaderBoardSchema is not a constructor".
What is the appropriate way of creating a schema that I need.
I have tried many variations looking online, but I keep getting the " LeaderBoardSchema is not a constructor".
The examples from other questions on S.O have not been able to help me much.
// leaderboard object that i want to save
leaderBoard = [
leaderOne= {
name: 'Ultimate Beast',
score: 2
},
leaderTwo= {
name: 'Masked Titan',
score: 9
},
leaderThree= {
name: 'Oranolio',
score: 7
},
leaderFour= {
name: 'Popularkiya',
score:1
},
leaderFive= {
name: 'Bootecia',
score: 11
},
];
// Database schema
const Schema = mongoose.Schema()
const LeaderBoardSchema = new mongoose.Schema({
leaderBoard:{
leaderOne : {
name: String,
score: Number
},
leaderTwo : {
name: String,
score: Number
},
leaderThree : {
name: String,
score: Number
},
leaderFour : {
name: String,
score:Number
},
leaderFive : {
name: String,
score: Number
}
}
}, {collection: 'leaderboard-data'});
const PlayerData = mongoose.model('LeaderBoard Data', LeaderBoardSchema);
// My attempt
const leaderBoardToSave = new LeaderBoardSchema({
leaderBoard:{
leaderOne : {
name: 'asdf',
score: 12
},
leaderTwo : {
name: 'sfgh',
score: 12
},
leaderThree : {
name: 'weh',
score: 12
},
leaderFour : {
name: 'asdf',
score:12
},
leaderFive : {
name: 'asdf',
score: 12
}
}
})
Currently your leaderBoard field is an object. To model an array of objects do the following with your schema:
const LeaderBoardSchema = new mongoose.Schema({
leaderBoard: [
{
name: String,
score: Number
}
]
}, {collection: 'leaderboard-data'});
as for the issue with the schema constructor. You're creating the mongoose model as follows const PlayerData = mongoose.model('LeaderBoard Data', LeaderBoardSchema);. But then you do new LeaderBoardSchema({...}). You need to use the mongoose model PlayerData instead. so to create a new leaderboard:
const leaderBoardToSave = new PlayerData({
leaderBoard: [
{
name: 'asdf',
score: 12
},
{
name: 'gds',
score: 12
},
{
name: 'adad',
score: 12
},
]
})

How to use unixtime with $dateToString mongodb

is't possible to use unixtime with $dateToString.
this is the schema:
var wifiSchema = mongoose.Schema({
ID: String,
Vendor: String,
SSID: String,
TimeStamp: {
date: Number,
},
AP: String,
MAC: String,
ID_frame: String,
RSSI: Number,
Type: String
}, { collection: 'wifiScan' });
var wifi = mongoose.model('wifi', wifiSchema);
and this is the mongoose function:
wifi.aggregate([
{$group:{_id:{"time" : "$TimeStamp.date"},uniqueCount: {$addToSet: "$MAC"}}},
{$project:{"time":1,uniqueCustomerCount:{$size:"$uniqueCount"}, yearMonthDayUTC: { $dateToString: { format: "%Y/%m/%d", date: new Date('$$TimeStamp.date') } } } },
{$sort:{'uniqueCustomerCount': -1 }}
]).limit(20).exec().then(notes => {
res.status(200).json({data:notes});
console.log(notes);
});
The problem that I get an error on converting the date variable from unix fo date format using $dateToString, this is the result I get:
{ _id: { time: 1529235720000 },
uniqueCustomerCount: 26,
yearMonthDayUTC: '1970/01/01' } ]
I don't know why I get is as '1970/01/01'. thanks for the help.
Second try:
I have tried this $project example also:
{$project:{"time":1,uniqueCustomerCount:{$size:"$uniqueCount"},"Time": { "$add": [ new Date(0), "$TimeStamp.date" ]} } },

I want to remove my array list

my array list is below:
this.array_of_name = ko.observableArray([
{ name: 'All Ways' },
{ name: 'Brand Cars' },
{ name: 'Carrom' },
{ name: 'Ginger' },
{ name: 'Honey' },
{ name: 'Jar Jar' },
{ name: 'Bert' },
{ name: 'Kitjar' },
{ name: 'Denise' },
{ name: 'Numeric' },
{ name: 'Length' },
{ name: 'Orange' },
{ name: 'Panasonic' },
{ name: 'Rabbit' },
{ name: 'Tarzan' },
{ name: 'USA' },
{ name: 'Yield' },
{ name: 'Zen' }
]);
i want to remove all items from it using javascript or knockout.
And also want to add search functionality using javascript or knockout.
var newArray = [];
var a=["a","b","c"];
for(var i=0;i<a.length;i++)
if(a[i]!=="a") newArray.push(a[i]);
Or another approach
removeAll = function(ary, elem) {
return ary.filter(function(e) { return e != elem });
}
to make empty, just assign empty array to your variable.
ex: this.array_of_name = ko.observableArray([]);

Resources