// Models
var mongoose = require('mongoose');
var ProfileSchema = new mongoose.Schema({
fullName: {
type: String,
required: true
}
// profileImage: {type: String, required: true}
});
module.exports = mongoose.model('Profile', ProfileSchema)
// Controllers
var Profile = require('../models/profile');
var multer = require('multer');
var upload = multer({dest: 'uploads/'});
exports.createProfile = (upload.single('profileImage'), function (req, res, next) {
var profileData = {
fullName: req.body.fullName,
// profileImage: req.file
}
console.log(req.file);
console.log('req.file: ', JSON.stringify(req.file));
console.log(profileData);
Profile.create(profileData, function (err, profile) {
if (err) {
// console.log(err);
res.end();
return;
// res.send(err);
}
Profile.create(function (err, profiles) {
if (err) {
res.end();
// res.send(err);
return;
}
res.json(profileData);
});
});
});
I'm trying to use middleware to add text and image at the same time in the MongoDB database. However, my fields aren't populated and when I try to print it out in the console it says req.file(): undefined. I've researched on the other issues and it states using 'upload.single()' will solve the problem. In my case, it didn't! The first section is my model view(Schema), the second section is my controllers' view.
I'm fairly new to Mongoose and don't think my approach on deleting an item in a subdocument is the right one.
I have the following schema setup:
//DEPENDENCIES
var mongoose = require('mongoose');
var contactSchema = new mongoose.Schema({
name:{type:String},
age:{type:Number}
});
var phoneSchema = new mongoose.Schema({
number:{ type: String },
phoneType:{ type: Number }
})
var memberSchema = new mongoose.Schema({
firstname: {
type: String
},
lastname: {
type: String
},
phone:[phoneSchema],
contacts:[contactSchema]
});
//RETURN MODEL
module.exports = mongoose.model('member', memberSchema);
To remove an item from the phone, in my Express API, I first find the parent then reference "remove" for the child ID, like this. But it does not work.
router.route('/owner/:ownerId/phone/:phoneId')
.delete(function(req, res){
Member.findOne({_id: req.body.ownerId}, function(err, member){
member.phone.remove({_id: req.body.phoneId}, function(err){
if(err)
res.send(err)
res.json({message: 'Success! Phone has been removed.'})
});
});
});
Figured out that I was looking for req.body and was actually needing req.params.
Also found right syntax on Mongoose docs:
router.route('/owner/:ownerId/phone/:phoneId')
.delete(function(req, res){
Member.findOne({_id: req.params.ownerId}, function(err, member){
member.phone.id(req.params.phoneId).remove();
member.save(function (err) {
if (err) return handleError(err);
console.log('the sub-doc was removed');
});
});
});
Through a single form I'm trying to build a game object that consists of a 'game_name', and a 'game_length', and a ref association by ObjectId to a 'player'. What I have is building both objects but the player is not being saved in the players array in the Game model. Thanks for any help in advance.
Schema and Models
Game Schema/Model
var gameSchema = new mongoose.Schema({
course_name: String,
game_length: Number,
players: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Game'
}],
created: {type: Date, default: Date.now}
})
var Game = mongoose.model('Game', gameSchema);
Player Schema/Model
var playerSchema = new mongoose.Schema({
player_name: String,
})
var Player = mongoose.model('Player', playerSchema);
Post Route
app.post('/games', function(req, res){
Game.create(req.body.game, function(err, newGame){
if (err) console.log(err);
Player.create(req.body.player, function(err, newPlayer){
if (err) console.log(err);
newGame.players.push(newPlayer);
})
res.redirect('games');
})
})
It looks like you just need to call .save:
app.post('/games', function(req, res){
Game.create(req.body.game, function(err, newGame){
if (err) console.log(err);
Player.create(req.body.player, function(err, newPlayer){
if (err) console.log(err);
newGame.players.push(newPlayer);
newGame.save(function(err) {
if (err) return console.log(err);
// saved!
res.redirect('games');
});
})
})
})
I'm trying to create a model favorites.js and populate it with user.js and dishes.js, so if a user posted a favourite dish using only the id of that dish, it will store also the user and the list of favourites of that user.
Here is what I have done so far. As I'm new to this my code could have more problems than what I think. Here is my favourites model and favRouter; see how they are populated.
models/ favorites:
var mongoose = require('mongoose');
//var Dishes = require('../models/dishes');
var Schema = mongoose.Schema;
var timestamps = require('mongoose-timestamp');
mongoose.Promise = global.Promise;
// create schema
var favSchema = new Schema({
id: {
type: String,
required: true
},
createdBy: {
type: Schema.ObjectId,
ref: 'User'
},
dishes: {
type: Schema.ObjectId,
ref: 'Dish'
}
},{
timestamps: true
});
var Favorites = mongoose.model('favorites', favSchema);
module.exports= Favorites;
models/dishes:
// Dependencies
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//var timestamps = require('mongoose-timestamp');
require('mongoose-currency').loadType(mongoose);
var Currency = mongoose.Types.Currency;
mongoose.Promise = global.Promise;
// create schema
var commentSchema = new Schema({
rating: {
type: Number,
min: 1,
max: 5,
required: true
},
comment: {
type: String,
required: true
},
postedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
},{
timestamps: true
});
var dishSchema = new Schema({
name: {
type: String,
required: true,
unique: true
},
image:{
type: String,
required: true,
},
category: {
type: String,
required: true,
},
label: String || '',
price: Currency,
description: {
type: String,
required: true
},
comments: [commentSchema]
},{
timestamps: true
});
dishSchema.path('price').get(function(num) {
return (num/100);
});
dishSchema.path('price').set(function(num) {
return (num )
});
// model
var Dishes = mongoose.model('Dish', dishSchema);
module.exports= Dishes;
modles/user:
// Dependencies
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//var timestamps = require('mongoose-timestamp');
require('mongoose-currency').loadType(mongoose);
var Currency = mongoose.Types.Currency;
mongoose.Promise = global.Promise;
// create schema
var commentSchema = new Schema({
rating: {
type: Number,
min: 1,
max: 5,
required: true
},
comment: {
type: String,
required: true
},
postedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
},{
timestamps: true
});
var dishSchema = new Schema({
name: {
type: String,
required: true,
unique: true
},
image:{
type: String,
required: true,
},
category: {
type: String,
required: true,
},
label: String || '',
price: Currency,
description: {
type: String,
required: true
},
comments: [commentSchema]
},{
timestamps: true
});
dishSchema.path('price').get(function(num) {
return (num/100);
});
dishSchema.path('price').set(function(num) {
return (num )
});
// model
var Dishes = mongoose.model('Dish', dishSchema);
module.exports= Dishes;
routers/favRouter:
var express = require('express');
var bodyParser = require('body-parser');
var Verify = require('./verify');
var Favorites = require('../models/favorites');
var favRouter = express.Router();
favRouter.use(bodyParser.json());
favRouter.route('/')
.all(Verify.verifyOrdinaryUser)
.get(function(req, res, next){
Favorites.find({})
.populate(['createdBy', 'dishes'])
.exec(function(err, fav) {
if(err) throw err;
res.json(fav);
});
})
.post(function(req, res, next){
Favorites.create(req.body, function(err, fav){
if(err) throw err;
req.body.createdBy = req.decoded._doc._id;
console.log('Created favorite dish!');
res.json(fav);
});
})
.delete(Verify.verifyOrdinaryUser, Verify.verifyAdmin, function(req, res, next){
Favorites.remove({}, function(err, resp){
if (err) throw err;
res.json(resp);
});
});
favRouter.route('/:objectId ')
.all(Verify.verifyOrdinaryUser)
.get(function(req, res, next){
Favorites.findById(req.params.objectId)
.populate(['createdBy', 'dishes'])
.exec(function(err, fav){
if (err) throw err;
res.json(fav);
});
})
.put(function(req, res, next){
Favorites.findByIdAndUpdate(req.params.objectId, {
$set: req.body
},{
new: true
}, function(err, fav){
if (err) throw err;
// Delete the recent comment then add the new one
fav.id(req.params.objectId).remove();
req.body.createdBy = req.decoded._doc._id;
fav.push(req.body);
fav.save(function(err, fav){
if(err) throw err;
console.log('Updated comments!');
res.json(fav);
});
});
})
.delete(function(req, res, next){
Favorites.findByIdAndRemove(req.params.objectId, function(err, fav){
if (fav.id(req.params.objectId).postedBy != req.decoded._doc._id) {
var err = new Error('You are not authorized to perform this operation!');
err.status = 403;
return next(err);
}
fav.id(req.params.objectId).remove();
fav.save(function(err, resp){
if(err) throw err;
res.json(resp)
})
});
});
module.exports = favRouter;
routers/dishRouter:
var express = require('express');
var bodyParser = require('body-parser');
var Verify = require('./verify');
var Dishes = require('../models/dishes');
var dishRouter = express.Router();
dishRouter.use(bodyParser.json());
dishRouter.route('/')
.get(Verify.verifyOrdinaryUser, function(req, res, next){
Dishes.find({})
.populate('comments.postedBy')
.exec(function(err, dish) {
if(err) throw err;
res.json(dish);
});
})
.post(Verify.verifyOrdinaryUser, Verify.verifyAdmin, function(req, res, next){
Dishes.create(req.body, function(err, dish){
if(err) throw err;
console.log('Dish created!');
var id = dish._id;
res.writeHead(200, {
'Content-Type': 'text/plain'
});
res.end('Added the dish with id: '+ id);
});
})
.delete(Verify.verifyOrdinaryUser, Verify.verifyAdmin, function(req, res, next){
Dishes.remove({}, function(err, resp){
if (err) throw err;
res.json(resp);
});
});
dishRouter.route('/:dishId')
.get(Verify.verifyOrdinaryUser, function(req, res, next){
Dishes.findById(req.params.dishId)
.populate('comments.postedBy')
.exec( function(err, dish){
if (err) throw err;
res.json(dish);
})
})
.put(Verify.verifyOrdinaryUser, Verify.verifyAdmin, function(req, res, next){
Dishes.findByIdAndUpdate(req.params.dishId, {
$set: req.body
},{
new: true
}, function(err, dish){
if(err) throw err;
res.json(dish);
})
})
.delete(Verify.verifyOrdinaryUser, Verify.verifyAdmin, function(req, res, next){
Dishes.findByIdAndRemove(req.params.dishId, function(err, resp){
if(err) throw err;
res.json(resp)
});
});
// Comments
dishRouter.route('/:dishId/comments')
.all(Verify.verifyOrdinaryUser)
.get(function(req, res, next){
Dishes.findById(req.params.dishId)
.populate('comments.postedBy')
.exec(function(err, dish) {
if(err) throw err;
res.json(dish.comments);
});
})
.post(function(req, res, next){
Dishes.findById(req.params.dishId, function(err, dish){
if(err) throw err;
req.body.postedBy = req.decoded._doc._id;
dish.comments.push(req.body);
dish.save(function(err, dish){
if(err) throw err;
console.log('Updated comments !');
res.json(dish);
});
});
})
.delete(Verify.verifyAdmin, function(req, res, next){
Dishes.findById(req.params.dishId, function(err, dish){
if (err) throw err;
for (var i = (dish.comments.length -1); i>= 0; i--){
dish.comments.id(dish.comments[i]._id).remove();
}
dish.save(function(err, dish){
if (err) throw err;
res.writeHead(200,{'Content-Type': 'text/plain'});
res.end('Deleted all comments');
});
});
});
dishRouter.route('/:dishId/comments/:commentId')
.all(Verify.verifyOrdinaryUser)
.get(function(req, res, next){
Dishes.findById(req.params.dishId)
.populate('comments.postedBy')
.exec(function(err, dish){
if (err) throw err;
res.json(dish.comments.id(req.params.commentId));
});
})
.put(function(req, res, next){
Dishes.findById(req.params.dishId, function(err, dish){
if (err) throw err;
// Delete the recent comment then add the new one
dish.comments.id(req.params.commentId).remove();
req.body.postedBy = req.decoded._doc._id;
dish.comments.push(req.body);
dish.save(function(err, dish){
if(err) throw err;
console.log('Updated comments!');
res.json(dish);
});
});
})
.delete(function(req, res, next){
Dishes.findById(req.params.dishId, function(err, dish){
if (dish.comments.id(req.params.commentId).postedBy != req.decoded._doc._id) {
var err = new Error('You are not authorized to perform this operation!');
err.status = 403;
return next(err);
}
dish.comments.id(req.params.commentId).remove();
dish.save(function(err, resp){
if(err) throw err;
res.json(resp)
})
});
});
module.exports = dishRouter;
My project files:
I have a User model:
user.model.js
var UserSchema = new Schema({
username: { type: String, required: true, unique: true },
location: { 'type': {type: String, enum: "Point", default: "Point"}, coordinates: { type: [Number], default: [0,0]} },
});
UserSchema.index({location: '2dsphere'});
And have an Express route:
user.route.js
function create(req, res) {
User.create(req.body, function(err, user) {
if (err) return res.send(err);
return res.send(user);
})
}
user.test.js
describe('test_user', function() {
it('create user', function(done) {
request('http://localhost/user')
.post('/')
.send({
username: 'john',
password: "123"
})
.end(function(err, res) {
if (err) cb(err);
done()
});
});
});
I have a drop_databse.js file, it run every time before run test:
drop_databse.js
var MongoClient = require('mongoose/node_modules/mongodb').MongoClient
MongoClient.connect('mongodb://localhost/miccity_test', function(err, db) {
if (err) return console.log(err);
db.dropDatabase(function(err) {
if (err) return console.log('drop databse failed!! :\n' + err);
db.close();
})
})
when I test
when I run test:
$ node drop_database.js && mocha
test_user
✓ create user
1 passing (21ms)
But, I notice user collection in database has not index of location field !
But I create a single file:
test.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/miccity_test');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'mongodb connection error:'));
var UserSchema = new Schema({
username: { type: String, required: true, unique: true },
location: { 'type': {type: String, enum: "Point", default: "Point"}, coordinates: { type: [Number], default: [0,0]} },
});
UserSchema.index({location: '2dsphere'});
var User = mongoose.model('User', UserSchema);
User.create({username: "test"}, function (err) {
if (err) console.log(err);
})
And run: node drop_databse.js && node test.js, then i check the index of location, it exist!
Is it mean mocha can not create index of collection?
Edit:
i found the trick way:
use Model.ensureIndexes to Sends ensureIndex commands to mongo for each index declared in the schema.
function create(req, res) {
User.ensureIndexes(function(err){
User.create(req.body, function(err, user) {
if (err) return res.send(err);
return res.send(user);
})
}
it is maybe a bug for mongoose, I already submit this issue to github.