I am using nodejs, express and jade templating engine to display books from my database to the index.jade file, i want all the books in the database to displayed on the index.jade page
i created a the book model below
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/nodeauth');
var db = mongoose.connection;
var bookSchema = mongoose.Schema({
title: String,
category: String,
description: String,
author: String,
publisher: String,
price: Number,
stock: Number,
cover: String
});
var Book = module.exports = mongoose.model('Book', bookSchema, 'books');
i called my bookModel in the index.js Below in the get request that renders the index.jade view
var express = require('express');
var router = express.Router();
var Book = require('../models/bookModel');
/* GET home page. */
router.get('/', function(req, res, next) {
Book.find({}, function (err, books) {
if (err) {console.log(err);}
res.render('index', {books: books}, { title: 'Members' });
});
});
module.exports = router;
the problem is that it keeps running an endless loop with out displaying anythin
this is my index.jade
extends layout
block content
.content
each book in books
.book
img(src="/images/book.cover", width="150px", height="200px")
h4.book-title book.title
h6.book-dtls Price: book.price SDG
p.book-desc book.description
a.btn.btn-primary.view(href="/books/details/book._id") View Book
first use #{book.title} to show data on pug
img(src="/images/book.cover", width="150px", height="200px")
h4.book-title #{book.title}
h6.book-dtls Price: #{book.price} SDG
p.book-desc #{book.description}
a.btn.btn-primary.view(href="/books/details/book._id") View Book
and may be there is problem in book.books.
So first you should use console.log(book) to check data
`
Related
I'm writing an Node.js REST API using express web server and mongoDB as DB server.
The project's directory tree is the following :
https://i.stack.imgur.com/LFWGt.png
When I try to access "/new/test" route, I'm getting the error "Cannot GET /new/test". By accessing this path it should create an new entry into the DB based on "firstname" URL parameter.
Routes.js :
'use strict';
module.exports = function(app) {
var americaine = require('../controllers/americaineController');
// Firstname Routes
app.route('/new/:firstname')
.post(americaine.new_firstname);
};
DB entry creation function is located on Controller.js :
'use strict';
var mongoose = require('mongoose'),
Firstname = mongoose.model('Firstname');
exports.new_firstname = function(req, res) {
var new_firstname = Firstname(req.params.firstname);
new_firstname.save(function(err, firstname) {
if (err)
res.send(err);
res.json(firstname);
});
};
Model.js :
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var FirstNameSchema = new Schema({
/*id: {
type: Number,
required: false
},*/
name: {
type: String,
required: true
}
});
module.exports = mongoose.model('Firstname', FirstNameSchema);
Do you guys have any ideas about my issue ? Thanks in advance.
Jérémy
change the method .post() to .get()
since you're actually doing a get request and not a post request.
I have a simple comments app which enables the user to enter a comment into the system via a form and these are then logged onto a list on the bottom of the page.
I wanted to modify it so that a user could click a comment once it is created and it would load up the associated content that goes with that comment.
My schema:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var CommentSchema = new Schema({
title: String,
content: String,
created: Date
});
module.exports = mongoose.model('Comment', CommentSchema);
My app.js routes:
app.use('/', routes);
app.use('/create', create);
app.use('/:title', show);
My show route:
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var Comment = mongoose.model('Comment', Comment);
router.get('/', function(req, res) {
Comment.findOne(function(err, comment){
console.log(comment.content)
});
});
module.exports = router;
I have three comments in my system and saved in my database, each with unique contents, But whenever I click on a comment, no matter what it is. I am only getting the content that is associated with the first comment.
Why is this?
You'll have to provide a condition for .findOne() to retrieve a specific document:
Model.findOne(conditions, [fields], [options], [callback])
Without one, an empty condition is implied that matches every document in the collection:
Comment.findOne({}, function ...);
And, .findOne() simply retrieves the 1st of those that are matched.
With the :title parameter in the route for show and title property in the Schema, one possible condition would be:
Comment.findOne({ title: req.params.title }, function ...);
Though, if the titles aren't unique in order to find the "right" one, you'll have make the condition more specific. The _id or id would be the most distinct.
app.use('/:id', show);
Comment.findOne({ id: req.params.id }, function ...);
// or
Comment.findById(req.params.id, function ...);
Also adjusting any links and res.redirect()s to fill pass the id for :id.
I am receiving an empty array with the following code:
var mongoose = require('mongoose');
var db = mongoose.createConnection('localhost', 'mytestapp');
var SurveySchema = require('../models/Survey.js').SurveySchema;
var Survey = mongoose.model('SurveySchema', SurveySchema, 'surveys');
var UserSchema = require('../models/Survey.js').User;
var User = mongoose.model('user', UserSchema, 'users');
exports.getSurveysForUser = function(User) {
return function (req, res) {
User
.findOne({_id: req.params.userId})
.populate('surveys')
.exec(function (err, user){
if (err) return res.json({error: err})
else {
var surveyList=[];
surveyList = user.surveys;
console.log(surveyList);
console.log("user: "+ user);
res.json(surveyList);
}
});
}};
This is the console output:
[ ]
user: { __v: 2,
_id: 52939b8c22a7efb720000003,
email: 'a#b.de',
password: '202cb962ac59075b964b07152d234b70',
surveys: []
}
These are the Mongoose models:
exports.SurveySchema = new Mongoose.Schema({
description : String,
questions : [question] });
exports.User = new Mongoose.Schema({
name : String,
email: { type: String, unique: true },
password: { type: String, required: true},
surveys : [{type: Schema.ObjectId, ref: 'SurveySchema'}] });
Btw:
I already tried User.findOne(...) and then a Survey.find() in the callback. It seemed that the second statement was not even executed. Apparently i am very new to mongoose..and i can't find a way around this problem
Do you have any ideas how to help me?
I couldn't really find any helpful solution here, but the problem shouldn't be a big one.
Thanks in advance, its really keeping me up for days now!!
Edit: So this is the index.js with the method:
var mongoose = require('mongoose');
var db = mongoose.createConnection('localhost', 'mytestapp');
var SurveySchema = require('../models/Survey.js').SurveySchema;
var Survey = mongoose.model('SurveySchema', SurveySchema, 'surveys');
var UserSchema = require('../models/Survey.js').User;
var User = mongoose.model('user', UserSchema, 'users');
//.. here are some more methods..
exports.getSurveysForUser = function(User) {
return function (req, res) {
User
.findOne({_id: req.params.userId})
.populate('surveys')
.exec(function (err, user){
if (err) return res.json({error: err})
else {
var surveyList=[];
surveyList = user.surveys;
console.log(surveyList);
console.log("user: "+ user);
res.json(surveyList);
}
});
}};
//this is the code, that saves a response to a survey
exports.addResponse = function(ResponseSet) {
return function (req, res) {
console.log("bin da: addResponse");
console.log("response zu: " + req.body.surveyId);
console.log("von user : " + req.body.userId);
//für user speichern
var pUser = User.findOne({_id:req.body.userId}, function (error, user) {
// Maybe populate doesnt work, because i only push the ID?
user.surveys.push(Mongoose.Types.ObjectId(req.body.surveyId));
user.save();
}
);
var pSurvey = Survey.findOne({_id:req.body.surveyId}, function (error, survey) {
survey.responses.push(Mongoose.Types.ObjectId(req.params.id));
survey.save();
}
);
//responseSet speichern
var responseSet = new ResponseSet(req.body);
responseSet.save(function(error, responseSet) {
if (error || !responseSet) {
res.json({ error : error });
} else {
res.json(responseSet);
}
});
};
};
And this is the app.js, which consumes the index.js:
var Mongoose = require('mongoose');
var db = Mongoose.createConnection('localhost', 'mytestapp');
var SurveySchema = require('./models/Survey.js').SurveySchema;
var Survey = db.model('surveys', SurveySchema);
var UserSchema = require('./models/Survey.js').User;
var User = db.model('user', UserSchema);
var ResponseSetSchema = require ('./models/Survey.js').responseSet;
var ResponseSet = db.model('responseSet', ResponseSetSchema);
var express = require('express')
, routes = require('./routes')
, http = require('http')
, path = require('path')
, passport = require('passport')
, pass = require('./config/pass')
, user_routes = require('./routes/user');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views/app');
//app.engine('html', require('ejs').renderFile);
app.use(express.static(__dirname + '/views/app'));
app.use(express.cookieParser());
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.session({ secret: 'securedsession' }));
app.use(passport.initialize()); // Add passport initialization
app.use(passport.session()); // Add passport initialization
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.all('/secure', pass.ensureAuthenticated);
app.get('/', function (req, res)
{
res.render('index.html');
} );
// some more code...
app.get('/api/secure/userSurveys/:userId', routes.getSurveysForUser(User));
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
Hope it helpsto fight the problem!
Many many thanks in advance!! :)
Try changing:
surveys: [{type: Schema.ObjectId, ref: 'SurveySchema'}] });
to
surveys: [{type: Schema.Types.ObjectId, ref: 'SurveySchema'}] });
Also, make sure you have surveys pushed as children to User.surveys.
http://mongoosejs.com/docs/populate.html, here this section talks about your requirement in detail:
Refs to children
We may find however, if we use the aaron object, we are unable to get a list of the stories. This is because no story objects were ever 'pushed' onto aaron.stories."
Ok, it took quite a lot to figure out the issue:
exports.getSurveysForUser = function(User) {
...
};
The var User - model is not being injected into the scope properly. Change to:
exports.getSurveysForUser = (function(User) {
...
})(User);
The returned function's signature for middleware do not require User model to be passed as they are re-initiated and passed within the middleware code.
In index.js, change this
app.get('/api/secure/userSurveys/:userId', routes.getSurveysForUser(User));
to
app.get('/api/secure/userSurveys/:userId', routes.getSurveysForUser());
I also request you to self test your code and read as many docs as possible. Also, there can be multiple ways of reaching your goals. With time and practice you will conquer them all. Good luck!
So i found a solution!
Firstly it seemed, that the mongoose Schemas were not correctly required.
So in the models, i did mongoose.model('modelname', schemaname); for every model and now i only use mongoose.model(...) for every model in the index.js.
Secondly i found out about an even more critical thing: There were suddenly no user.surveys for my testuser anymore! I am sure that it was filled with surveys a few days ago. Because i tested my code several times and some surveys were pushed to that collection. Maybe i dropped the collection it in some testing..i don't really remember. So i pushed a survey manually in the mongodb console and tested it again --> worked! the user.surveys were populated! maybe the function worked yesterday and didn't need any change. I am so sorry, if that was a waste of time.
Bad thing is, that right now the exports.addResponse(....) is only saving a response, but is not pushing the IDs to the arrays user.surveys and survey.responses. This seems to be a synchronizing Problem and i will figure that out somehow.
Anyways, thank you for your help and time!
This is my first time writing a MVC app in Node/Express/Mongoose so I could really use some help. My .find() command just doesn't find anything! :(
Structure is that I have a an /app folder in the root. /app folder contains /models (schemas), /controllers and /views in it. And I have app.js outside in the root.
Somewhere in app.js:
// all necessary config/setup stuff..
var mongoose = require('mongoose');
mongoose.connect(config.db);
var app = express();
require('./config/routes')(app)
In my routes.js file:
var skills = require('../app/controllers/skills');
app.get('/', skills.showall);
My controller skills.js contains:
var Skill = require('../models/skill');
exports.showall = function(req, res) {
Skill.find({}, function(err, docs){
if (!err) {
res.render('index', {title: 'Skilldom', skills: docs});
}
else {
throw err;
}
});
}
Finally my Model skill.js contains:
var mongoose = require('mongoose');
//Skill schema definition
var skillSchema = new mongoose.Schema({
name: String,
length: String,
});
var Skill = mongoose.model('Skill', skillSchema);
module.exports = Skill;
My index view renders, so I see the content from my index.jade template, but for some reason the find command in the model is not fetching anything. I can confirm that my database (in MongoHQ) has real data.
Any thoughts?
Change your Skill.js for this
var mongoose = require('mongoose');
mongoose.set('debug', true);
//Skill schema definition
var skillSchema = new mongoose.Schema({
name: String,
length: String,
});
var Skill = mongoose.model('Skill', skillSchema);
module.exports = Skill;
After that, you can see at the console if mongoose is doing your queries.
I was in the same situation as you describe and it turns out I didn't understand the magic of mongoose collection naming, in your code it will try to load the "skills" and if that's not what it's named in your mongo nothing will be returned. Should really toss a "so such collection" error instead imho.
This below method gives an alternate name for your collection
var skillSchema = new mongoose.Schema({
name: String,
length: String,
},{collection : 'Skill'});
or
var Skill = mongoose.model('Skill', skillSchema,''Skill);
I'm trying to add in my first plugin - mongoose-text-search.
https://npmjs.org/package/mongoose-text-search
I'm getting the error: How to Error: text search not enabled that I can't figure out.
I have my schema in seperate file where it gets compiled into a model that I export. (Works fine.)
blogSchema.js
var mongoose = require('mongoose');
var textSearch = require('mongoose-text-search');
var blogSchema = new mongoose.Schema({
title: String,
author: String,
}],
});
// give our schema text search capabilities
blogSchema.plugin(textSearch);
var Blog = mongoose.model('Blog', blogSchema);
exports.Blog = Blog;
This is relevant code for the server side. When the client sends a request to /search/,
the socket hangs up - Got error: socket hang up and on the server side I get the
How to Error: text search not enabled message.
server.js
var express = require('express')
, mongoose = require('mongoose')
, textSearch = require('mongoose-text-search');
var search_options = {
project: 'title -_id'
};
app.get('/search', function (req, res) {
console.log("inside text search");
Reading.textSearch('writing', search_options, function (err, output) {
if (err) throw err;
console.log(output);
});
});
Thanks.
You need to enable text search on the MongoDB server as described here as it's disabled by default.