Get the count of Javascript object in jade from mongoose/node data - node.js

I have a node app which is tied to a mongo database and has routing with express and templates generated by Jade. Using express I am getting a list of all users using the following function:
/* GET users listing. */
router.get('/', function(req, res) {
User.find({}, function(err, users) {
var userMap = {};
users.forEach(function(user){
userMap[user._id] = user;
});
res.render('page', {
users : userMap
})
});
});
In my jade view I can display the users easily using:
each user in users
li= user.username
But I also want to get a count of the obj coming back and display that data on the page. I have tried #{users.size} and {users.length} as well as a few other variations to no avail. I am not sure what I am doing wrong. Do I need to add a count method to the model?

your variable users is an object not a array try
Object.keys(users).length

Related

Node js adding new property to a array of objects when returning from mongoose collection

I am creating app using nodejs, express, mongoose. And mongodb.user is the mongoose schema model and I am trying to fetch user array of objects, that query is perfect and my problem is I want to add new property for each user. I have tried as follows. But it does not add to the collection.
exports.memberlist = function(req, res) {
user.find({}).exec(function(err, collection) {
collection.forEach(function(member){
member.city = 'Colombo';
collection.push(member);
});
res.send(collection);
});
};
you can do like this
in Schema level create create virtual property
userSchema.virtual('city').get(function () {
return 'Colombo';
});
in controller level
exports.memberlist = function(req, res,next)
{
user.find({}).exec(function(err, users)
{
if(!err)
{
res.json(200, users.toObject({virtual: true}));
}
else
{
next(err);
}
});
};
By default, Mongoose doesn't allow to add a property to an object extracted from MongoDB DB. To do so, you have two alternatives :
1/ before exec statement you add a lean() method :
user.find({}).lean().exec(function(err, collection) {do whatever you want with collection}
2/ collection = collection.toObject();

Retrieve unique ID from MongoDB using Express.js

I'm fairly new to MongoDB. My current code is as follows:
var app = express();
app.post('/myDB', function(req, res) {
console.log('POSTed data');
db.myDB.insert(req.body, function(err, doc) {
console.log(err);
res.json(doc);
});
})
I know that when data is inserted into MongoDB, a unique _id key:value pair is created. I would like to have access to this unique id upon data insertion.
But from what I know currently (admittedly not a whole lot), I would have to do an app.get('/myDB/:id')... (Or something similar) in order to access that unique identifier. Is there a way to do this without having to make an extra http request?
In MongoDB, with the Node.js driver, you can get the inserted id from the callback function's second parameter. The syntax is:
collection.insert(docs[[, options], callback])
where docs is a single document object or an array of documents, options is an options object and callback is a callback function to run after the record is inserted. The second paramter returns an array of documents inserted.
Thus you can retrieve the inserted id this way:
var app = express();
app.post('/myDB', function(req, res) {
console.log('POSTed data');
db.myDB.insert(req.body, {w:1}, function(err, doc) {
console.log("Record added as "+ doc[0]._id);
res.json(doc);
});
You can read more on the docs here.

How to create routes with unique ids in NodeJS

So i am working on a project with node, express, mongoose en mongodb. I am able to create/save a topic to the db. but when the topic is saved/created i want to redirect the user to the topic details page of that created topic (so basically every created topic has its own unique url based of the id, like so -> localhost:3000/topicdetail/id)
The problem with me is that upon redirecting i get an error saying: Error: Failed to lookup view "error" in views directory "/Users/Grace/Desktop/QA/views"
So my main question is am i redirect it correctly with its own unique id or am i doing something else wrong. Any help is welcome.
my code is the following:
var mongoose = require('mongoose');
var Topic = require('../models/topic');
var db = require('../config/database');
var express = require('express');
var router = express.Router();
// render the start/create a new topic view
router.get('/', function(req, res) {
res.render('newtopic');
});
// save topic to db
router.post('/',function(req, res, next){
console.log('The post was submitted');
var topic = new Topic
({
"topicTitle": req.body.topicTitle,
"topicDescription": req.body.topicDescription,
"fbId": req.body.userIdFB,
"twId": req.body.userIdTW
})
topic.save(function (err, topic)
{
if(err){
return next(err)
console.log('Failed to save the topic to the database');
}
else
{
console.log('Saved the topic succesfully to the database');
// each topic has its own unique url
res.redirect('/topicdetail/{id}');
}
})
});
module.exports = router;
Calling res.redirect('/topicdetail/{id}'); won't insert any ID. Express won't reformat the string. It takes your defined redirect, in this case /topicdetail/{id}and performs it. Just like you would insert it into your browser.
To redirect your detail view you could do something like:
res.redirect('/topicdetail/' + topic._id); and replace topic.id with something like your document ID or another identifier.
Just a reminder: Your detail route needs a param in the route definition. Example: app.get('/verification/:token', users);. The :token is your param. More about in the routing guide.

node.js/express/mongoose noob issue

I just start to use node.js with express and mongoose, and I have a stupid question...
Somewhere in my routes.js file, I have the following section :
// DASHBOARD SECTION, GET MY GROUPS
app.get('/dashboard', isLoggedIn, function(req, res) {
var Group = require('../app/models/group'); //adding mongoose Schema
Group.find({"groupDetails.userId" : req.user._id})
.exec(function(err, myGroups) {
if (err)
res.send(err);
var myGroups = myGroups;
//console.log("myGroups: " + myGroups); // check with "heroku logs"
res.render('dashboard.ejs', {
user : req.user,
myGroups : myGroups
});
});
});
This code works. When someone browse the dashboard page, I receive "myGroups" which is an array with all the groups for the current logged in user.
Now, here is my question :
Actually when someone browse the dashboard page, I would like to make a second query (based on the exact same pattern) to get all groups and all files for the current logged in user.
Then I will send "user", "myGroups" and "myFiles" to the dashboard page.
How can I do that ?
I tried several things with no result so far... I think I'm a little bit lost in node.js callback functions :D
Thanks a lot for your help.
You have two options here:
1) deal with callback hell (callback inside callback inside...) to retrieve 3 sets of data. This way is least elegant and efficient
2) Use a library that will do the job asynchronously and have one callback when all the data is retrieved, you can use async library which is just awesome. In this case you will have just one callback in which you can access all the data you have fetched.
Here's what you can do with async in your case:
var async = require('async');
..........
app.get('/dashboard', isLoggedIn, function(req, res) {
var Group = require('../app/models/group'); //adding mongoose Schema
var User = require('../app/models/user'); //adding mongoose Schema
var Files = require('../app/models/files'); //adding mongoose Schema
async.parallel({
groups: function(callback){
Group.find(...).exec(callback);
},
users: function(callback){
Users.find(...).exec(callback);
},
files: function(callback){
Files.find(...).exec(callback);
}
}, function(err, results) {
if (err)
res.send(err);
var groups = results.groups;
var users = results.users;
var files = results.files;
res.render('dashboard.ejs', {
user : req.user,
myGroups : groups,
users: users,
files: files
});
});
});

How to loop over mongodb array with express and monk to create a page for each element?

I am building a web app with express, nodejs and monk. I am trying to create a page for each element of an array in my mongodb database.
That data is already in the collection called collections with the key coll_list like so:
{ "_id" : ObjectId("53dbaefd3d85d57492506f1f"), "coll_list" : [ "data_pagename1",
"data_pagename2", "data_pagename3" ] }
I thought it might be possible to loop over all the elements in coll_list with something like:
router.get('/index', function(req, res) {
var db = req.db;
var collection = db.get('collections');
collection.find( "coll_list" , function(e,docs) {
for (elems in docs) {
res.render(elems, {
elems : docs
});
}
});
});
Any suggestions or help/pointers on how to do this would be greatly appreciated.
Use req.params
router.get('/coll/:id',
function(req,res){
//access the id by req.params.id
//req.params.id will essentially be the _id of the document
//use it to obtain data from mongoDB and render the page using that data
//From the front end you make the call to /coll/<ObjectId> like
// /coll/53dbaefd3d85d57492506f1f and you get that id in req.params.id and use it to
//render data specific to that _id.
});
Thus, using a single route you would be able to create a page for every item in coll_list

Resources