Method does not return whole object - javascript

When I call the method buildCommand, it does not return the property message, but I found out that if I remove some properties out of buildCommand, it works.
This is the method I call
const buildCommand = (commandJSON) => {
return new Command({
prefix: commandJSON.prefix,
command: commandJSON.command,
aliases: commandJSON.aliases,
parameters: commandJSON.parameters,
message: commandJSON.message,
response: commandJSON.response,
commandMedium: commandJSON.commandMedium,
enabled: commandJSON.enabled,
isDefault: commandJSON.isDefault,
permission: commandJSON.permission,
cooldown: commandJSON.cooldown,
});
};
This is how I call the method
const newCommand = buildCommand(commandJSON);
commandJSON looks like this
{ prefix: '!', command: 'laugh', message: 'hahaha' }
UPDATE 2
Here is my whole Command Model
const mongoose = require('mongoose');
const commandSchema = mongoose.Schema({
prefix: {
type: String,
default: '!',
},
command: {
type: String,
required: true,
},
aliases: {
type: Array,
},
parameters: {
type: Array,
},
message: {
type: String,
},
response: {
type: String,
enum: ['chat', 'whisper'],
default: 'chat',
},
commandMedium: {
type: String,
enum: ['offline', 'online', 'both'],
default: 'both',
},
enabled: {
type: Boolean,
default: true,
},
isDefault: {
type: Boolean,
default: false,
},
permission: {
type: String,
enum: ['everyone', 'subscriber', 'vip', 'moderator', 'broadcaster'],
default: 'everyone',
},
cooldown: {
globalCooldown:{type:Boolean, default:false},
globalDuration:{type:Number, default:0},
userDuration:{type:Number,default:0},
}
});
module.exports = mongoose.model('Commands', commandSchema, 'TwitchUsers');

Command is just a Mongoose model. There's nothing async in there, you can (and should) remove the async/await stuff.
You can simply do const newCommand = new Command(commandJSON), job done.

Related

Trying to use mongoose with vue and getting error

any time i try to import this the page throws the error of
Uncaught TypeError: Cannot read properties of undefined (reading 'split')
import { User } from '#/assets/schemas'
export default {
name: 'HomeView',
mounted() {
//const user = User.findOne({ id: '1002401206750150836' })
console.log('user')
}
}
when i comment out the import it works but when i add the import back i get that error this is the code for the Schemas.js
const mongoose = require('mongoose');
const User = new mongoose.Schema({
id: { type: String, unique: true, required: true},
bank: { type: Number, default: 2000 },
wallet: { type: Number, default: 0},
chips: { type: Number, default: 0},
level: { type: Number, default: 1},
totalxp: { type: Number, default: 0},
xp: { type: Number, default: 0},
favcolor: { type: String, default: "White"},
cooldowns: {
daily: { type: Date },
monthly: { type: Date },
buychips: { type: Date },
}
})
const Guild = new mongoose.Schema({
id: { type: String, unique: true, required: true},
welcome_channel_id: { type: String, default: null },
new_member_role_id: { type: String, default: null }
})
module.exports = { User: mongoose.model("User", User), Guild: mongoose.model("Guild", Guild) }
Mongoose is not a frontend library, it can not be used with Vue. It relies on Node.js functionality which doesn't exist in the browser. Mongoose is only meant to be used on a backend Node.js server.

Mongoose populate() is returning an empty array

I am trying to use mongoose populate function but in response I am getting empty array. I know there are several questions talking about the same subject but none worked for my case.
My objective is to populate my Order document.
This is how my schemas are organized:
Menu.js
const mongoose = require("mongoose");
const { Schema } = mongoose;
const Food = require("./Food");
const Drink = require("./Drink");
const MenuSchema = new Schema({
code: {
type: mongoose.ObjectId,
required: true,
unique: true,
},
name: {
type: String,
required: true,
},
food: {
type: [Food.schema],
required: false,
},
drinks: {
type: [Drink.schema],
required: false,
},
type: {
type: String,
},
createdAt: {
type: Date,
default: Date.now,
},
});
module.exports = mongoose.model("Menu", MenuSchema);
Note: Im using Food.schema and Drink.schema inside my Arrays instead of making a ref. Im storing the Food and Drink models inside of the Menu model
Food.js
const mongoose = require("mongoose");
const { Schema } = mongoose;
const FoodSchema = new Schema({
code: {
type: mongoose.ObjectId,
required: true,
unique: true,
},
description: {
type: String,
required: true,
},
ingredients: {
type: [],
required: false,
default: [],
},
stock: {
type: Number,
required: true,
},
type: {
type: String,
enum: ["starter", "main", "dessert"],
required: true,
},
price: {
type: Number,
required: true,
},
createdAt: {
type: Date,
default: Date.now,
},
});
module.exports = mongoose.model("Food", FoodSchema);
Drink.js
const mongoose = require("mongoose");
const { Schema } = mongoose;
const DrinkSchema = new Schema({
code: {
type: mongoose.ObjectId,
required: true,
unique: true,
},
description: {
type: String,
required: true,
},
stock: {
type: Number,
required: true,
},
price: {
type: Number,
required: true,
},
createdAt: {
type: Date,
default: Date.now,
},
});
module.exports = mongoose.model("Drink", DrinkSchema);
Order.js
const mongoose = require("mongoose");
const { Schema } = mongoose;
const OrderSchema = new Schema({
code: {
type: mongoose.ObjectId,
required: true,
unique: true,
},
type: {
type: String,
required: true,
enum: ["restaurant", "takeaway", "delivery"],
},
food: {
type: [{ type: mongoose.ObjectId, ref: "Food" }],
required: false,
default: [],
},
drinks: {
type: [{ type: mongoose.ObjectId, ref: "Drink" }],
required: false,
default: [],
},
orderValue: Number,
client_id: {
type: mongoose.ObjectId,
ref: "Client",
required: false,
},
createdAt: {
type: Date,
default: Date.now,
},
});
module.exports = mongoose.model("Order", OrderSchema);
This is the controller where I'm trying to make my populate work. Whenever I remove the populate method I get the _id references for the Food and Drink arrays.
TableController.js
exports.getOrderFromTable = async (req, res) => {
const { code, tableCode } = req.params;
try {
const foundRestaurant = await Restaurant.findOne({ code: code });
const foundTable = foundRestaurant.tables.filter(
(table) => table.code == tableCode
);
console.log(foundTable[0].order_id);
const foundOrder = await Order.findOne({
_id: foundTable[0].order_id,
})
.populate("food")
.populate("drinks");
res.send(foundOrder);
} catch (err) {
res.json({ message: err });
}
};
And this is what the mongoose debugger returns when I run the controller:
Mongoose: restaurants.findOne({ code: new ObjectId("62a60dcb9fe25d276815675c") }, { projection: {} })
new ObjectId("62a60ece9fe25d27681567b7")
Mongoose: orders.findOne({ _id: new ObjectId("62a60ece9fe25d27681567b7") }, { projection: {} })
Mongoose: foods.find({ _id: { '$in': [ new ObjectId("62a60e039fe25d276815677d"), new ObjectId("62a60e169fe25d2768156785") ], [Symbol(mongoose#trustedSymbol)]: true }}, { skip: undefined, limit: undefined, perDocumentLimit: undefined, projection: {}})
Mongoose: drinks.find({ _id: { '$in': [ new ObjectId("62a60e259fe25d276815678d"), new ObjectId("62a60e3c9fe25d276815679c") ], [Symbol(mongoose#trustedSymbol)]: true }}, { skip: undefined, limit: undefined, perDocumentLimit: undefined, projection: {}})
And finally this is the JSON file I get when I do a GET http request using Postman:
{
"_id": "62a60ece9fe25d27681567b7",
"code": "62a60ece9fe25d27681567b6",
"type": "restaurant",
"food": [],
"drinks": [],
"orderValue": 25,
"createdAt": "2022-06-12T16:05:34.513Z",
"__v": 0
}
Thank you for any help. I've been really struggling with this method.

.findOne / .findById keep running if no result is found

I face an issue that i can't resolve alone.
I have a MongoDB collection, in this collection i have 1 document atm.
When i use .findById(_id) or .findOne({_id : id}) with the right _id, everything works.
When i use .findById(_id) or .findOne({_id : id}) with the wrong _id (for test purposes), i have no response (no undefined, no null, nothing) from the DB and my request keep running.
Ty for your time, take care !
EDIT :
Document :
export interface OrderDocument extends mongoose.Document {
user: UserDocument['_id'];
asset_bought: AssetDocument['_id'];
asset_b_symbol: string;
asset_sold: AssetDocument['_id'];
asset_s_symbol: string;
exchange: ExchangeDocument['_id'];
exchange_name: string;
is_draft: Boolean;
amount: number;
atm_price: number;
date: Date;
}
Collection's schema :
const orderSchema = new mongoose.Schema(
{
_id: { type: mongoose.Schema.Types.ObjectId },
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'users',
required: true,
},
asset_bought: {
type: mongoose.Schema.Types.ObjectId,
ref: 'assets',
required: true,
},
asset_b_symbol: {
type: String,
required: true,
},
asset_sold: {
type: mongoose.Schema.Types.ObjectId,
ref: 'assets',
required: true,
},
asset_s_symbol: {
type: String,
required: true,
},
exchange: {
type: mongoose.Schema.Types.ObjectId,
ref: 'exchanges',
required: true,
},
exchange_name: {
type: String,
required: true,
},
is_draft: { type: Boolean, default: false },
amount: { type: Number, required: true },
atm_price: { type: Number, required: true },
date: { type: Date, required: true },
},
{ timestamps: true }
);
Service
export async function findAndPopulateOrders(
searchType: 'id' | 'one' | 'many',
query: FilterQuery<OrderDocument>,
_collections: Array<string>
) {
const collections = _collections.join(' ');
if (searchType === 'id') {
return await OrderModel.findById(query).populate(collections);
} else if (searchType === 'one') {
return await OrderModel.findOne(query).populate(collections);
} else if (searchType === 'many') {
return await OrderModel.find(query).populate(collections);
} else {
return {};
}
}

What's the difference between document.property and document.get('property')?

I have a mongoose document that has timestamps option enabled. I want to make decisions based on this timestamps but I noticed something weird according to my understanding.
I tried to get those values the traditional way (document.createdAt) but that returns undefined. But if I use document.get('createdAt') the value comes as in the database. The docs don't say anything about this. My question is: ¿Why timestamps behave this way?
Edit
The schema I'm using has an array of embedded schemas:
const Customer = new mongoose.Schema({
roles: {
type: [{
type: String,
enum: 'app b2b iot'.split(' '),
}],
default: 'app',
set: (value = []) => (value.includes('app')
? value
: value.concat('app')),
},
email: {
address: {
type: String,
trim: true,
lowercase: true,
set(email) {
this._previousEmail = this.email.address
return email
},
},
verified: {
type: Boolean,
},
token: String,
},
nickname: {
type: String,
trim: true,
},
recoveryToken: String,
gender: String,
birthday: String,
lastLogin: Date,
isAnonymous: {
type: Boolean,
default: false,
},
devices: [Device],
});
Device schema:
const Device = new mongoose.Schema({
customer: {
type: ObjectId,
ref: 'Customer',
required: true,
},
handle: {
type: String,
},
platform: {
type: String,
required: true,
set: toLowerCase,
},
info: Mixed,
smartFilterTags: [{
type: String,
}],
paidUntil: Date,
nh: {
tier: String,
_id: {
type: ObjectId,
},
location: {
type: {
type: String,
enum: ['Point'],
default: 'Point',
},
coordinates: [{
type: Number,
}],
},
})
I have a base plugin that apply when I compile models:
function basePlugin(schema) {
schema.add({
archivedAt: Date,
})
schema.set('timestamps', true)
schema.set('toJSON', {
virtuals: true,
})
schema.set('toObject', {
virtuals: true,
})
}

Manipulating Mongoose/MongoDB Array using Node.js

I've noticed there's little documentation and info about how I should manipulate an array of objects using Mongoosejs.
I have the following model/Schema for an User:
'use strict';
/**
* Module Dependencies
*/
var bcrypt = require('bcrypt-nodejs');
var crypto = require('crypto');
var mongoose = require('mongoose');
/**
* Custom types
*/
var ObjectId = mongoose.Schema.Types.ObjectId;
var userSchema = new mongoose.Schema({
email: { type: String, unique: true, index: true },
password: { type: String },
type: { type: String, default: 'user' },
facebook: { type: String, unique: true, sparse: true },
twitter: { type: String, unique: true, sparse: true },
google: { type: String, unique: true, sparse: true },
github: { type: String, unique: true, sparse: true },
tokens: Array,
profile: {
name: { type: String, default: '' },
gender: { type: String, default: '' },
location: { type: String, default: '' },
website: { type: String, default: '' },
picture: { type: String, default: '' },
phone: {
work: { type: String, default: '' },
home: { type: String, default: '' },
mobile: { type: String, default: '' }
}
},
activity: {
date_established: { type: Date, default: Date.now },
last_logon: { type: Date, default: Date.now },
last_updated: { type: Date }
},
resetPasswordToken: { type: String },
resetPasswordExpires: { type: Date },
verified: { type: Boolean, default: true },
verifyToken: { type: String },
enhancedSecurity: {
enabled: { type: Boolean, default: false },
type: { type: String }, // sms or totp
token: { type: String },
period: { type: Number },
sms: { type: String },
smsExpires: { type: Date }
},
friends: [{
friend: { type: ObjectId, ref: 'User' },
verified: { type: Boolean, default: false }
}]
});
/* (...) some functions that aren't necessary to be shown here */
module.exports = mongoose.model('User', userSchema);
So as you can check I defined Friends inside User like this:
friends: [{
friend: { type: ObjectId, ref: 'User' },
verified: { type: Boolean, default: false }
}]
Now the question is how can I add, edit and delete this array in a Node.js script?
BOTTOMLINE: How can I manipulate arrays that are inside MongoDB Schemas, using Node.js and Mongoose.js? Do I always have to create a Schema function or can I access it directly?
EDIT (13/07/2014): So far I've created a HTTP GET that gives me the array like this:
app.get('/workspace/friends/:userid', passportConf.isAuthenticated, function (req, res) {
User.find({_id: req.params.userid}, function (err, items) {
if (err) {
return (err, null);
}
console.log(items[0].friends);
res.json(items[0].friends);
});
});
But this only returns an array of friendIds, but what if I want to create some sort of '/workspace/friends/:userid/del/:friendid' POST, or add POST. I can't seem to figure out how I can get this done.
You can do something like following
app.get('/workspace/friends/:userid/delete/:friendId', passportConf.isAuthenticated, function (req, res) {
User.findOne({_id: req.params.userid}, function (err, user) {
if (err) {
return (err, null);
}
for (var i = 0; i < user.friends.length; i++) {
if (user.friends[i]._id === req.params.friendId) {
user.friends = user.friends.splice(i,1)
}
}
user.save(function(err, user, numAffected){
if (!err )res.json(user)
res.send('error, couldn\'t save: %s', err)
})
});
});
What it says in mongoose docs is that
"The callback will receive three parameters, err if an error occurred, [model] which is the saved [model], and numberAffected which will be 1 when the document was found and updated in the database, otherwise 0.
The fn callback is optional. If no fn is passed and validation fails, the validation error will be emitted on the connection used to create this model."
If you need to manipulate arrays, you should convert these in objects before.
User.findOne({_id: req.params.userid}, function (err, user) {
if (err) {
return (err, null);
}
var user = user.toObject();
//... your code, an example =>
delete user.friends;
res.json(user);
});
Regards, Nicholls

Categories

Resources