I have the following schema:
import mongoose, { Model, Schema, model, Types, Document } from "mongoose"
import { isEmpty } from "lodash"
import User from "./User"
import { generateImageStyles, ImageStylePrefixes } from "../server/common/util"
import { PresaveImageMetaData, PostsaveImageMetaData } from "./User"
export enum BadgeTrigger { ... }
export enum BadgeCategory { ... }
export interface IBadge {
_id?: Types.ObjectId
name: string,
image: PresaveImageMetaData,
triggerType?: BadgeTrigger,
triggerAmount?: number,
order?: number,
hidden?: boolean,
category: BadgeCategory,
description?: string,
}
// Include fields that are generated automatically or virtuals that exist on the document by not the schema
// Instance methods also go here
export interface IBadgeDocument extends IBadge, Document<Types.ObjectId, unknown, IBadge> {
image: PostsaveImageMetaData
}
// Static methods go here
interface IBadgeModel extends Model<IBadge> { }
const BadgeSchema = new Schema<IBadgeDocument, IBadgeModel>({
name: {
type: String,
required: true
},
image: { type: Object, required: true },
triggerType: {
type: String,
required: false,
enum: Object.values(BadgeTrigger)
},
triggerAmount: { type: Number },
order: { type: Number },
// This acts as the "retired" field
hidden: { type: Boolean },
category: {
type: String,
required: true,
enum: Object.values(BadgeCategory),
},
description: { type: String }
},
{ timestamps: true }
)
// Add instance methods here
BadgeSchema.methods = {}
// Add model static methods
BadgeSchema.statics = { }
// Add presave / postsave and other middlework hooks here
BadgeSchema.pre('save', function (next) {
const styles: ImageStylePrefixes[] = ['large_square', 'medium_square', 'thumb_square']
if (this.image && this.image.url && !this.image.styles) {
this.image.styles = generateImageStyles(this.image.url, styles)
}
next()
})
async function deleteBadgeReferences(badge:
mongoose.Document<unknown, any, IBadge>
& IBadge
& { _id: any }
) {
// Remove the badge references in the user model
await User.updateMany({ _badges: badge._id }, {
$pull: {
_badges: badge._id
}
})
}
/**
* Remove references to badge when it's deleted
*/
BadgeSchema.pre('remove', async function(next) {
await deleteBadgeReferences(this)
next()
})
BadgeSchema.pre('deleteOne', async function(next) {
await deleteBadgeReferences(this)
next()
})
const Badge = model<IBadgeDocument>('Badge', BadgeSchema)
export default Badge
I create an array of badges to add as an array like so:
const playerRatingBadges: IBadge[] = [
{
_id: new Types.ObjectId("000000000000000000000004"),
name: "Player Rating 1.0 Test Badge",
image: TestImageData,
category: BadgeCategory.Milestones,
description: "Desc for player rating test badge",
triggerAmount: 1.0,
triggerType: BadgeTrigger.PlayerRating
},
{
_id: new Types.ObjectId("000000000000000000000005"),
name: "Player Rating 3.5 Test Badge",
image: TestImageData,
category: BadgeCategory.Milestones,
description: "Desc for player rating test badge",
triggerAmount: 3.5,
triggerType: BadgeTrigger.PlayerRating
},
{
_id: new Types.ObjectId("000000000000000000000006"),
name: "Player Rating 6.0 Test Badge",
image: TestImageData,
category: BadgeCategory.Milestones,
description: "Desc for player rating test badge",
triggerAmount: 6.0,
triggerType: BadgeTrigger.PlayerRating
}
]
And then call the insertMany as so await Badge.insertMany(playerRatingBadges)
However, when viewing the data in the database I see the following result:
{
"_id" : ObjectId("000000000000000000000004"),
"name" : "Player Rating 1.0 Test Badge",
"image" : {
"url" : "version2/jahfkjnasdkjfbnajsdbfhjb.photo.jpg",
"type" : "jpg",
"name" : "photo.jpg",
"styles" : {
"thumb_square" : "thumb_square/jahfkjnasdkjfbnajsdbfhjb.photo.png",
"large_square" : "large_square/jahfkjnasdkjfbnajsdbfhjb.photo.png"
}
},
"triggerType" : "PlayerRating",
"triggerAmount" : NumberInt(1),
"category" : "milestones",
"description" : "Desc for player rating test badge",
"__v" : NumberInt(0)
}
{
"_id" : ObjectId("000000000000000000000005"),
"name" : "Player Rating 3.5 Test Badge",
"image" : {
"url" : "version2/jahfkjnasdkjfbnajsdbfhjb.photo.jpg",
"type" : "jpg",
"name" : "photo.jpg",
"styles" : {
"thumb_square" : "thumb_square/jahfkjnasdkjfbnajsdbfhjb.photo.png",
"large_square" : "large_square/jahfkjnasdkjfbnajsdbfhjb.photo.png"
}
},
"triggerType" : "PlayerRating",
"triggerAmount" : 3.5,
"category" : "milestones",
"description" : "Desc for player rating test badge",
"__v" : NumberInt(0)
}
{
"_id" : ObjectId("000000000000000000000006"),
"name" : "Player Rating 6.0 Test Badge",
"image" : {
"url" : "version2/jahfkjnasdkjfbnajsdbfhjb.photo.jpg",
"type" : "jpg",
"name" : "photo.jpg",
"styles" : {
"thumb_square" : "thumb_square/jahfkjnasdkjfbnajsdbfhjb.photo.png",
"large_square" : "large_square/jahfkjnasdkjfbnajsdbfhjb.photo.png"
}
},
"triggerType" : "PlayerRating",
"triggerAmount" : NumberInt(6),
"category" : "milestones",
"description" : "Desc for player rating test badge",
"__v" : NumberInt(0)
}
{
"_id" : ObjectId("000000000000000000000003"),
"name" : "Milestone Test Badge",
"image" : {
"url" : "version2/jahfkjnasdkjfbnajsdbfhjb.photo.jpg",
"type" : "jpg",
"name" : "photo.jpg",
"styles" : {
"thumb_square" : "thumb_square/jahfkjnasdkjfbnajsdbfhjb.photo.png",
"large_square" : "large_square/jahfkjnasdkjfbnajsdbfhjb.photo.png"
}
},
"category" : "milestones",
"description" : "Desc for milestone test badge",
"createdAt" : ISODate("2022-04-25T17:39:10.279+0000"),
"updatedAt" : ISODate("2022-04-25T17:39:10.279+0000"),
"__v" : NumberInt(0)
}
The badge that has the createdAt and updatedAt timestamps is the badge that was created in a different location using Badge.create({ ... }). Does auto management of timestamps just not work with insertMany?
Related
i want to build a cart for my website, this is the schema for the cart:
const productSchema = require("./product")[1];
const cartItemSchema = new Schema<CartItem>(
{
product: productSchema,
quantity: {
type: Number,
required: true,
min: [1, "Quantity can not be less then 1."],
},
},
{
timestamps: true,
}
);
const CartSchema = new Schema(
{
userID: {
type: Schema.Types.ObjectId,
ref: "User",
},
items: [cartItemSchema],
},
{ timestamps: true }
);
module.exports = model<Cart>("Cart", CartSchema);
the problem is, when I add a product in a specific user cart, while the same product is allready added to another user cart document, I get this error:
"message":"cannot add to cart E11000 duplicate key error collection: elec-store.carts index: items.productID_1 dup key: { items.productID: null }, stack: MongoError: E11000 duplicate key error collection: elec-store.carts index: items.productID_1 dup key
this is the add function
public async add(cartItem: CartItem, userID: string): Promise<Cart> {
let cartInDB = null;
await CartModel.findOne({ userID: userID }, (err, cart) => {
cartInDB = cart;
});
if (AppUtils.hasValue(cartInDB)) {
const index = cartInDB.items.findIndex(
(item) => item.product._id.toString() === cartItem.product._id
);
if (index !== -1) {
cartInDB.items[index].quantity =
cartInDB.items[index].quantity + cartItem.quantity;
cartInDB.items[index].product._id = cartItem.product._id;
const cartAfterAdding = await cartInDB.save();
return cartAfterAdding;
} else {
await CartModel.update(
{ _id: cartInDB._id },
{ $push: { items: cartItem } }
);
}
return cartInDB;
} else {
const itemsArray: CartItem[] = [];
itemsArray.push(cartItem);
let createdCart = new CartModel({
userID: userID,
items: itemsArray,
});
await createdCart.save(); \\ this is where the problem occurs
return createdCart;
}
}
and this is how my cart looks like in mongodb document:
db.carts.find().pretty()
{
"_id" : ObjectId("60ea9fb81b2b4c048c3b1544"),
"userID" : ObjectId("60dee5e1da81bd274cd304de"),
"items" : [
{
"_id" : ObjectId("60ea9fb81b2b4c048c3b1545"),
"product" : {
"_id" : ObjectId("60e62cb21f74572b7c0b3a30"),
"name" : "tv",
"description" : "the best tv",
"categoryID" : 2,
"quantity" : "2",
"serialNumber" : "226swaq12",
"price" : 2000,
"imgUrl" : "https://www.seekpng.com/png/full/774-7744281_samsung-electronics-samsung-electronic-product-png.png"
},
"quantity" : 6,
"createdAt" : ISODate("2021-07-11T07:37:29.790Z"),
"updatedAt" : ISODate("2021-07-11T07:38:15.583Z")
},
{
"_id" : ObjectId("60eaa16b1b2b4c048c3b155d"),
"product" : {
"_id" : ObjectId("60e066009be1060748201ad3"),
"name" : "samsung tv",
"description" : "the best tv",
"quantity" : "2",
"categoryID" : 2,
"serialNumber" : "2212",
"price" : 2000,
"imgUrl" : "https://www.seekpng.com/png/full/774-7744281_samsung-electronics-samsung-electronic-product-png.png"
},
"quantity" : 9,
"updatedAt" : ISODate("2021-07-11T07:46:19.313Z"),
"createdAt" : ISODate("2021-07-11T07:44:43.764Z")
}
],
"createdAt" : ISODate("2021-07-11T07:37:29.792Z"),
"updatedAt" : ISODate("2021-07-11T07:46:19.314Z"),
"__v" : 0
}
I use mongoose.Schema to create new schemas and then when making reference to a different schema I do it like this:
product: { type: mongoose.Schema.Types.ObjectId, ref: 'product' },
If later you need to show also the product info (db.carts.find()), you can use populate() to replace the reference for all the product entries.
You can use upsert true.
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ],
hint: <document|string> // Available starting in MongoDB 4.2
}
)
For example -
db.books.update(
{ item: "ZZZ135" }, // Query parameter
{ // Replacement document
item: "ZZZ135",
stock: 5,
tags: [ "database" ]
},
{ upsert: true } // Options
)
This may help: Mongo Update
my partial filter is deleting document, but user is not matching that requirement, am I using partial filter incorectly?
Thanks
const postSchema = new mongoose.Schema(
{
title: { type: String },
description: { type: String },
image: { type: String },
price: { type: String },
location: { type: String },
image: { type: Array },
author: {
type: String,
ref: 'User'
},
authorPremium: {
type: Boolean,
default: true,
index:true
},
reported: {
type: Boolean,
default: false
},
reportClear: {
type: Boolean,
default: false
}
},
{
timestamps: true
}
);
// users who are not premium will have posts deleted after 20 seconds
postSchema.index({ createdAt: 1 }, { expireAfterSeconds: 20, partialFilterExpression: { authorPremium: false } });
module.exports = mongoose.model('Post', postSchema);
partial filer should not allow the authorPremium which is true to be deleted, but only delete is authorPremium is false... please advise.
return from mongo index
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.posts"
},
{
"v" : 2,
"key" : {
"createdAt" : 1
},
"name" : "createdAt_1",
"ns" : "test.posts",
"expireAfterSeconds" : 120,
"background" : true
},
{
"v" : 2,
"key" : {
"authorPremium" : 1
},
"name" : "authorPremium_1",
"ns" : "test.posts",
"background" : true
},
{
"v" : 2,
"key" : {
"timestamps" : 1
},
"name" : "timestamps_1",
"ns" : "test.posts",
"expireAfterSeconds" : 20,
"background" : true
}
]
it seems when I use mongo cmd some of my old setting remained.. and some new? So how can I completly clear these old ttl settings when I am testing and ensure only the ones I want are there?
It looks like your .index(...) does not work because you already have old index on createdAt field and mongoose won't drop the old one. To synchronize the indexes with your schema you can use Model.syncIndexes
More on how .index() works and why .syncIndexes() was introduced can be found here.
Basically I have the following schema.
{
...,
description: {
type: String,
required: true,
trim: true
},
tags: {
type: [{
type: String
}]
},
lessons: [{
name: String,
description: String,
video_path: String,
comments: [
{
user: mongoose.Schema.ObjectId,
content: String,
createdAt: {
type: Date,
default: Date.now
}
}
]
}]
,
createdAt: {
type: Date
}
}
I want to insert the following object to the comments array of a lesson object when the id of the lesson object is given.
{
userId: "5e1b4790f7a3ca42accfeed3",
content: "First comment"
}
The following is what I have tried. However it doesn't throw any error, but it's not inserting any comments to the DB also. Thanks for any helpful advice.
addComment: async (courseId, lessonId, userId, content, callback) => {
Course.update(
{ _id: courseId, "lessons._id": lessonId },
{
$push: {
comments: {
user: userId,
content: content
}
}
},
function(err, data) {
if (err) {
console.log(err);
return callback(err, null);
} else {
console.log(data);
return callback(null, data);
}
}
);
}
EDIT:
Collection data:
{
"_id" : ObjectId("5e1b4790f7a3ca42accfeed3"),
"tags" : [ "mathematics", "beginner", "fundamentals" ],
"name" : "Mathematics Toobox",
"description" : "Mathematics includes the study of such topics as quantity (number theory), structure (algebra), space (geometry), and change (mathematical analysis).",
"price" : 1500,
"lessons" : [
{
"_id" : ObjectId("5e1b48d9f7a3ca42accfeed4"),
"name" : "Welcome to the course",
"description" : "Welcome to Mathematics Toolbox course\n I’ll be your instructor for this course that runs for xx weeks ending on XXXXX.\n1. Access the technology tutorial located on your My Home page if you are new to the learning Hub, this online learning management system.",
"video_path" : "uploads\\1578846427336-Shakira - Hips Don't Lie ft. Wyclef Jean.mp4"
},
{
"_id" : ObjectId("5e1e8f80cf166a2cb82b7a5e"),
"name" : "Number system",
"description" : "Baby just love me love me love me\nBaby just hold me hold me hold me\nOh love me ",
"video_path" : "uploads\\1579061121969-Ellis - Migraine (feat. Anna Yvette) [NCS Release].mp4"
}
],
"createdAt" : ISODate("2020-01-12T16:21:36.778Z"),
"__v" : 0,
"cover_path" : "uploads\\1578846099107-img_4.jpg"
}
There are a few problems in your schema.
I think you want to have an array of string tags.
Also you need to use ref property to make a reference to the User model.
So schema must be updated like this:
(I assume that you used User in model creation.)
const mongoose = require("mongoose");
const courseSchema = new mongoose.Schema({
description: {
type: String,
required: true,
trim: true
},
tags: {
type: [String]
},
lessons: [
{
name: String,
description: String,
video_path: String,
comments: [
{
user: {
type: mongoose.Schema.ObjectId,
ref: "User"
},
content: String,
createdAt: {
type: Date,
default: Date.now
}
}
]
}
],
createdAt: {
type: Date
}
});
module.exports = mongoose.model("Course", courseSchema);
Now you can use findByIdAndUpdate method with push and filtered positional operator $.
to add a comment like this:
Course.findByIdAndUpdate(
{ _id: courseId },
{
$push: { "lessons.$[lesson].comments": { user: userId, content } }
},
{
arrayFilters: [{ "lesson._id": lessonId }],
new: true
},
function(err, data) {
if (err) {
console.log(err);
return callback(err, null);
} else {
console.log(data);
return callback(null, data);
}
}
);
Test:
Let's say you have an user with _id: 5e20954dc6e29d1b182761c9, and a course like this:
{
"tags": [
"tag1",
"tag2"
],
"_id": "5e209631a90e651e9c238df2",
"description": "description1",
"lessons": [
{
"comments": [],
"_id": "5e209631a90e651e9c238df3",
"name": "lesson1 name",
"description": "lesson1 description",
"video_path": "lesson1 video_path"
}
],
}
When you send a comment with these values:
courseId = "5e209631a90e651e9c238df2",
lessonId = "5e209631a90e651e9c238df3",
userId = "5e20954dc6e29d1b182761c9",
content = "Comment Content"
The result will be:
{
"_id" : ObjectId("5e209631a90e651e9c238df2"),
"tags" : [
"tag1",
"tag2"
],
"description" : "description1",
"lessons" : [
{
"comments" : [
{
"_id" : ObjectId("5e2099799edf132a08c2b997"),
"user" : ObjectId("5e20954dc6e29d1b182761c9"),
"content" : "Comment Content",
"createdAt" : ISODate("2020-01-16T20:12:25.243+03:00")
}
],
"_id" : ObjectId("5e209631a90e651e9c238df3"),
"name" : "lesson1 name",
"description" : "lesson1 description",
"video_path" : "lesson1 video_path"
}
]
}
This is what finally worked for me.
const newData = {
'lessons.$.comments': {
user: userId,
content: content
}
}
Course.updateOne({_id: courseId,'lessons._id': lessonId}, {'$push':
newData
}, function(err,num) {
console.log(num)
if(num.nModified > 0){
callback(null,num)
}
else if(err){
callback(err,null)
}
})
}
I have a mongoose schema for categories
import mongoose from 'mongoose';
import { imageScheme } from './data.schemas';
mongoose.plugin(require('mongoose-delete'));
mongoose.plugin(require('mongoose-timestamp'));
const Schema = mongoose.Schema;
const catScheme = new Schema({
title: {
type: String
},
subTitle: {
type: String
},
description: {
type: String
},
images: [imageScheme],
icon: {
type: String
},
deleteAt: {
type: Date,
default: null
}
});
const Category = mongoose.model('Category',catScheme);
export default Category;
my image schema is located in another file
const imageScheme = new Schema({
imageCaption : {
type: String
},
imageFileName: {
type: String,
required: true
},
imagePath: {
type: String,
required: true
}
});
and when I am using the model for creating new category its adding the timestamp and deleted for my images array which means its loading the plugins ( mongoose-delete , mongoose-timestamp ) into the sub schema
HOW TO AVOID THAT ?
that is the result
{
"_id" : ObjectId("5d5a822f20179023e008f10c"),
"deleteAt" : null,
"deleted" : false,
"title" : "Eyes and Ears",
"description" : "here you will find all ppe to keep your eye 6 sharp",
"icon" : "glass.svg",
"images" : [
{
"_id" : ObjectId("5d5a822f20179023e008f10e"),
"deleted" : false,
"imageCaption" : "Eyes and Ears",
"imageFileName" : "67acca17-3fc8-416c-bc00-8273770b2115.jpeg",
"imagePath" : "resources/images/67acca17-3fc8-416c-bc00-8273770b2115.jpeg",
"updatedAt" : ISODate("2019-08-19T11:04:15.756Z"),
"createdAt" : ISODate("2019-08-19T11:04:15.756Z")
},
{
"_id" : ObjectId("5d5a822f20179023e008f10d"),
"deleted" : false,
"imageCaption" : "Eyes and Ears",
"imageFileName" : "9f1c5b1f-c1be-48f2-a9bc-8294930fd4c9.jpeg",
"imagePath" : "resources/images/9f1c5b1f-c1be-48f2-a9bc-8294930fd4c9.jpeg",
"updatedAt" : ISODate("2019-08-19T11:04:15.756Z"),
"createdAt" : ISODate("2019-08-19T11:04:15.756Z")
}
],
"updatedAt" : ISODate("2019-08-19T11:04:15.756Z"),
"createdAt" : ISODate("2019-08-19T11:04:15.756Z"),
"__v" : 0
}
It looks like you are plugging the mongoose-delete and mongoose-timestamp in the whole database.
Have you tried the example provided in the plugin pages?
catScheme.plugin(mongoose-timestamp)
catScheme.plugin(mongoose-delete)
Here is the code that is trying to add a user to a schema:
var roomSchema = new Schema({
name: { type: String, required: true},
connections: { type: [ { userId: String } ] },
content: { type: String, default: ""},
isFull: { type: Boolean, default: false}
});
roomSchema.methods.addUser = function(username, callback) {
this.updateAsync( { $push: { connections: { userId: username } } } )
.then(function(status) {
return this.saveAsync();
})
.catch(function(afterPushErr) {
console.log('After push error');
throw afterPushErr;
})
.catch(function(saveErr) {
console.log('save Error');
throw saveErr;
});
Promise.all(this.connections)
.then(function() {
if(this.connections.length >= 5) {
this.updateAsync( { isFull: true })
.then(function(status) {
return;
})
.catch(function(updateErr) {
console.log('update Error!');
throw updateErr;
});
}
});
}
and then the code that calls it (which correctly imports the above function):
(Note: this is just a quick test function to make sure that there will only be a maximum of 5 users per room)
var populateRooms = function() {
var names = [
'asas',
'asas2',
'asas3',
'asas4',
'asas5',
'asas6'];
var emails = [
'asas#as.ca',
'asas2#as.ca',
'asas3#as.ca',
'asas4#as.ca',
'asas5#as.ca',
'asas6#as.ca'];
for(var i=0; i<6; ++i) {
Room.findOneAsync( { isFull: false })
.then(function(freeRoom) {
var newUser = new User({
username : names[i],
email : emails[i],
password : 'Asasas1',
isPlaced: true,
roomName: freeRoom.name
});
freeRoom.addUser(newUser.username);
return newUser;
})
.then(function(newUser) {
newUser.saveAsync();
})
.catch(function(err) {
throw err;
});
}
return true;
}
typically what I will see in the console is just the last user that was pushed rather than the entire list and because of that I am unable to see whether or not the list is of length >= 5.
On the mongo console I see this for the room schema:
{ "_id" : ObjectId("5882c3eefab3081700444972"), "name" : "1484964846968_0", "isFull" : false, "content" : "", "connections" : [ { "userId" : "asas5", "_id" : ObjectId("5882c3effab308170044497f") }, { "userId" : "asas6", "_id" : ObjectId("5882c3effab308170044497d") }, { "userId" : "asas4", "_id" : ObjectId("5882c3effab3081700444981") }, { "userId" : "asas6", "_id" : ObjectId("5882c3effab308170044497d") }, { "userId" : "asas5", "_id" : ObjectId("5882c3effab308170044497f") }, { "userId" : "asas4", "_id" : ObjectId("5882c3effab3081700444981") }, { "userId" : "asas3", "_id" : ObjectId("5882c3effab3081700444983") }, { "userId" : "asas", "_id" : ObjectId("5882c3effab3081700444987") }, { "userId" : "asas2", "_id" : ObjectId("5882c3effab3081700444985") }, { "userId" : "asas3", "_id" : ObjectId("5882c3effab3081700444983") }, { "userId" : "asas2", "_id" : ObjectId("5882c3effab3081700444985") }, { "userId" : "asas", "_id" : ObjectId("5882c3effab3081700444987") } ], "__v" : 12 } { "_id" : ObjectId("5882c3eefab3081700444973"), "name" : "1484964846978_1", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab3081700444974"), "name" : "1484964846980_2", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab3081700444975"), "name" : "1484964846980_3", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab3081700444976"), "name" : "1484964846981_4", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab3081700444977"), "name" : "1484964846981_5", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab3081700444978"), "name" : "1484964846982_6", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab3081700444979"), "name" : "1484964846984_7", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab308170044497a"), "name" : "1484964846984_8", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab308170044497b"), "name" : "1484964846984_9", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 }
Edit
this is the new error on the promise code for addUser
(node:4648) UnhandledPromiseRejectionWarning: Unhandled promise
rejection (rejection id: 1): TypeError: Cannot read property
'connections' of undefined (node:4648)
UnhandledPromiseRejectionWarning: Unhandled promise rejection
(rejection id: 2): TypeError: Cannot read property 'connections' of
undefined After push error After push error save Error save Error
Unhandled rejection TypeError: Cannot read property 'saveAsync' of
undefined
at C:\someApp\app\models\room-model.js:19:14
at tryCatcher (C:\someApp\node_modules\bluebird\js\release\util.js:16:23)
In the test function, you put the asynchronous call(Room.findOne) inside the for loop. Thus you got the same freeZoom for each loop.(which is not what you want)
Check this question: Asynchronous Process inside a javascript for loop
Another suggestion, this.update inside the addUser function is also asynchronous and may not act like what you want in some situation.