I learning node.js & mongoDB & mongoose, from maybe a week or 2. The problem I have right now is, I'm trying to save to db via mongoose .save(), but it doesn't work as expected. I'm watching a tutorial, and it's 3 days old, so should be up to date, but I'm getting strange error.
mpromise (mongoose's default promise library) is deprecated” error when testing [duplicate]
I read, here on stackoverflow that I can just add:
mongoose.Promise = require('bluebird');
It will work, but the code doesn't even go to the .save function, and don't trow an error. I'm not sure where the problem is.
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
let connectionString = 'mongodb://localhost:27017/mongo2';
mongoose.createConnection(connectionString, (err) => {
if (err) {
console.log(err);
return;
}
let Student = mongoose.model('Student', {
firstName: {type: String, required: true},
lastName: {type: String, required: true},
age: {type: Number},
facultyNumber: {type: String, unique: true}
});
let me = new Student({
firstName: 'Who',
lastName: 'amI',
age: 20,
facultyNumber: '9374823104'
});
me.save().then((info) => {
console.log(info);
}).catch((error) => {
console.log(error);
});
});
Edit: The result is: Getting the DB created, the collection too, but not the object. Everything is empty.
Very likely the problem is that your model does not have a schema attached.
const { Schema } = require('mongoose');
const StudentSchema = new Schema({
firstName: {type: String, required: true},
lastName: {type: String, required: true},
age: {type: Number},
facultyNumber: {type: String, unique: true}
}};
let Student = mongoose.model('Student', StudentSchema);
Related
I am making a node API. I am stuck at adding a comment to a story.
I am able to create a comment but instead of pushing it to a given story, it was trying to create a new instance of story.
Story.findOne(req.params.id, (err, foundstory) => {
if(err){
res.status(500).json({msg:err})
}else{
let comment = new Comment()
comment.body = req.body.body
comment.author = req.body.author
console.log(foundstory)
//save comment//
comment.save((err, comment) => {
if(err){
res.status(500).json({msg:err})
}else{
//pushing comment to comments array (ref) in story
foundstory.comments.push(comment)
foundstory.save()
res.status(200).json({msg:"Comment saved"})
}
})
}
})
Story Schema
import mongoose from 'mongoose'
import User from './user'
import Comment from './comment'
const Schema = mongoose.Schema
const ObjectID = mongoose.Schema.Types.ObjectId
const storySchema = new Schema({
//subdoc ref from user
author: {type: ObjectID, ref: 'User'},
//subdoc ref from comment
comments: [{
type: ObjectID,
ref: 'Comment'
}],
//contents of story//
title: {type: String, required: true},
body: {type: String, required: true},
date: {type: Date, default: Date.now()},
tags: [{type: String}]
})
module.exports = mongoose.model('Story', storySchema)
Comment Schema
import mongoose from 'mongoose'
import User from './user'
const Schema = mongoose.Schema
const ObjectID = mongoose.Schema.Types.ObjectId
const commentSchema = new Schema({
body : {type: String, required: true},
author: {type: ObjectID, ref: 'User'}
})
module.exports = mongoose.model('Comment', commentSchema)
I have an array of type "Comment" in my "Story" schema. My attempt is to push those comment to that array.
try changing your code like this:
Story.findById(req.params.id, (err, foundstory) => {
if (err) res.status(500).json({
msg: err
});
else if (!foundStory) res.status(400).json({
msg: "Story Not Found"
});
else {
let comment = new Comment();
comment.body = req.body.body;
comment.author = req.body.author;
//save comment//
comment.save(async (err, comment) => {
if (err) res.status(500).json({
msg: err
});
else {
foundstory.comments.push(comment._id);
await foundstory.save();
res.status(200).json({
msg: "Comment saved"
})
}
})
}
})
I've changed the findOne() method with findById(), also the 'foundstory.save()' method is an asynchronous call, so i used async\await to handle it.
Hope this helps :)
I have this Person and User models in my project:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const schema = new Schema({
name: {
type: String,
required: true
}
});
module.exports = mongoose.model('Person', schema);
and
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const schema = new Schema({
person: {
type: mongoose.SchemaTypes.ObjectId,
ref: 'Person',
required: true
},
email: {
type: String,
required: true
}
});
module.exports = mongoose.model('User', schema);
As we can see, a User has a reference to Person. I'm trying to find one User by either his email or by name of his Person. I tried many different approaches, like this:
exports.getUserByPersonNameOrEmail = async (uservalue) => {
var user = await User.findOne({
$or: [
{"person.name": uservalue},
{email: uservalue}
]
});
return user;
};
I also read about using the $elemMatch command, but it seems that it is used for documents with an array of children, instead of a specific child.
You would have to use mongoose populate and its match step during populate:
var user = await User.findOne({}).populate({
path: 'person',
match: { name: uservalue },
select: 'name -_id'
}).exec()
You can read more about it here. The idea basically is that you have to populate the actual references to person in your use model in order to query them. match applies a filter while they are being populated etc.
I am writing a cook book in node.js. Im new to this language and mongoDB concept. I identify that I need to have a user who has favorite recipes nad in favorite recipes I am going to store recipes
My model look like that and something its wrong here
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
userSchema = new Schema({
name: String,
userId: {type: String, required: true},
favorites: [{
type: Schema.Types.ObjectId,
ref: 'Favorites',
}],
});
favoritesSchema = new Schema({
name: String,
id: {type: Schema.Types.ObjectId},
recipes: [{
type: Schema.Types.ObjectId,
ref: 'Recipes',
}],
startOfRecipe: {type: Date},
});
recipeSchema = new Schema({
name: {type: String, unique: true},
});
const User = mongoose.model('User', userSchema);
const Favorites = mongoose.model('Favorites', favoritesSchema);
const Recipes = mongoose.model('Recipes', recipeSchema);
module.exports = {User, Favorites, Recipes};
I wrote a function which looking for user and then store favorite recipe
addFav(fav, userId) {
return new Promise(function(resolve, reject) {
schema.User.findOne({userId: userId}, function(err, user) {
if (err || !user) {
} else {
schema.Favorites.create({
name: fav,
}, (err, result) => {
if (err) throw err;
console.log(result);
resolve('noResult');
});
resolve(user);
}
});
});
}
and it saves but if I call my user the array favorites is always empty
{ favorites: [],
_id: 5cb32867d2dfea0cadd79ecb,
name: 'Anna',
userId:
'AF322',
__v: 0 }
What am I doing wrong? Could someone help me please :)
Please check below code. I created subschema of favorites & recipes, get user details using userId and push favorites object into favorites field
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
userSchema = new Schema({
name: String,
userId: {type: String, required: true},
favorites: [favoritesSchema],
});
favoritesSchema = new Schema({
name: String,
id: {type: Schema.Types.ObjectId},
recipes: [recipeSchema],
startOfRecipe: {type: Date},
});
recipeSchema = new Schema({
name: {type: String, unique: true},
});
const User = mongoose.model('User', userSchema);
addFav(fav, userId) {
return Schema.User.update({_id:userId}, {$set:{$push:{favorites:fav}}})
}
What I am trying to do is create a new collection, and push that collection into a specific User.collections array. I have read many stackoverflow posts and they all say to use either User.update() or User.findOneAndUpdate(). I am have no luck with either. I can create a Collection and that is saved to mongo so I know I am indeed accessing the db. Here is my code, if any of you can help I would appreciate it.
User Schema
const mongoose = require('mongoose');
const { Schema } = mongoose;
const userSchema = new Schema({
googleID: String,
givenName: String,
familyName: String,
collections: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "collection"
}
]
});
mongoose.model('users', userSchema);
Collection Schema:
const mongoose = require('mongoose');
const { Schema } = mongoose;
const collectionSchema = new Schema({
type: String,
name: String,
gamesCollected: [
{
id: Number
}
]
});
mongoose.model('collection', collectionSchema);
And my route:
router.get('/get_collection', (req, res) => {
const collection = new Collection({
type: 'SNES',
name: 'First SNES Collection',
gamesCollected: [{ id: 5353 }]
}).save();
User.update({googleID: req.user.googleID}, {$push: {collections: collection}});
});
Save is not a synchronous operation but asynchronous so you need to use the promise it returns and handle it and once it is complete then update the user model. Something among these lines:
router.get('/get_collection', async (req, res) => {
let collection = new Collection({
type: 'SNES',
name: 'First SNES Collection',
gamesCollected: [{ id: 5353 }]
})
await collection.save().exec();
await User.update(
{googleID: req.user.googleID},
{$push: {collections: collection._id}}
).exec();
});
I am trying to avoid duplicates from being saved in the system, and have implemented the model like so...
var mongoose = require('mongoose'),
ObjectId = mongoose.Schema.Types.ObjectId,
Schema = mongoose.Schema;
var User = require('../models/user.js');
var Stamp = new Schema({
name: {type: String, unique: true },
creatorId: {type: ObjectId, ref: 'User'},
dateAdded: {type: Date}
}, {collection: "stamps"});
Stamp.index({name: 'text'});
//to avoid duplicate names
Stamp.path('name').index({ unique: true });
module.exports = mongoose.model('Stamp', Stamp);
The code for saving the new stamp:
var new_stamp = new Stamp ({
name: stampname,
creatorId: creatorId,
dateAdded: dateAdded
});
new_stamp.save(function(err, results){
if(!err) {
console.log('stamp has been added to the db');
} else {
console.log("Error creating stamp " + err);
}
});
How do I stop from duplicates being saved?