app.get('/index', function(req, res){
Activities.find({}, function(err, activity){
if(err){
console.log(err);
}else{
res.render('index', {activities:activity});
}
});
Upcoming.find({}, function(err, upcomingActivity){
if(err){
console.log(err);
}else{
res.render('index', {upcoming:upcomingActivity});
}
});
});
I just want to get data of multiple collections and then pass it to index.ejs file so that i can use these data there.
I know using res.render() multiple times won't work but i have tried many things like saving founded data to variable , creating an object of these etc. But nothing
worked.
In your get response you should render only once the index page passing the parameters all together.
app.get('/index', function(req, res){
Activities.find({}, function(err, activity){
if(err){
console.log(err);
}else{
Upcoming.find({}, function(err, upcomingActivity){
if(err){
console.log(err);
}else{
res.render('index', {activity:activity, upcoming:upcomingActivity,});
}
});
}
});
});
It will work this way, since you have only a few collections but other way to do so is passing it as a global object and then rendering it.
Use then to render asynchronously
app.get('/index', (req,res) => {
Activities.find().then(activity => {
Upcoming.find().then(upcomingActivity => {
res.render('index', {Activities: activity, Upcoming: upcomingActivity})
}).catch(err => console.log(err))
}).catch(err => console.log(err))
})
Related
i have setup a simple express rest api and i want to get all posts when a certain route is requested from my rest server ("/api/posts")
i tried to console.log(posts) and it shows me the posts but when i try to go to the route http://localhost:5000/api/posts it shows me a blank page although console.logging the posts shows me the posts why is this
function getAllPosts() {
Post.find((err, posts) => {
if (err) {
console.error(err);
}
console.log(posts);
console.log("all posts requested");
return posts;
});
}
router
.route("/")
.get((req, res) => {
let posts = getAllPosts();
res.send(posts);
})
i expected to get the posts json when i go to http://localhost:5000/api/posts
when you are returning value from the getAllpost functions, routes are getting undefined value because of async. Try to edit your code like this:
function getAllPosts(req, res) {
Post.find((err, posts) => {
if (err) {
console.error(err);
}
console.log(posts);
console.log("all posts requested");
res.send( { data: posts} );
});
}
router
.route("/").get((req, res) => {
getAllPosts(req, res);
});
This has to do with the asynchronous nature of the code you have here. res.send is executing before Post.find() can resolve. You only want to res.send(posts) once the database query has finished fetching the data, if using callbacks, as you are in your example, you would do this inside of the callback. You could do something like this.
router
.route("/")
.get((req, res) => {
Post.find({}, (err, posts) => {
if (err) {
return res.status(500).send(err)
}
res.send(posts)
})
})
Recently I faced a problem where I couldn't get a recent insertion using MongoDB (mongoose) in node.js.
app.post("/addEvent", (req, res) => {
var myData = new Event(req.body);
myData.save().then(item => {
res.send("Event saved to database!");
})
.catch(err => {
res.status(400).send("Unable to save to database");
});
Event.find({categoryName:req.body.categoryName}, function(err, events) {
if (err) throw err;
Car.find({categoryName:req.body.categoryName}, function(err, cars) {
if (err) throw err;
/**some_code_here**/
});
});
some_foo(app, req.body.categoryName);
res.redirect(301, '/groups' + req.body.categoryName);
});
So, when I try to collect all the events via Event.find({}), I get zero events.
But after the request ends, I can see my event in the database.
What I want is to have access to the recently added event inside the POST request.
Any ideas?
Thanks!
If you want to search for recent saved Event, you must wait for callback of your myData.save() function. If you don't wait for it, Event.find() will be fire in parralel of your myData.save()
try :
app.post("/addEvent", (req, res) => {
var myData = new Event(req.body);
myData.save().then(item => {
//res.send("Event saved to database!");
Event.find({categoryName:req.body.categoryName}, function(err, events) {
if (err) throw err;
Car.find({categoryName:req.body.categoryName}, function(err, cars) {
if (err) throw err;
/**some_code_here**/
});
some_foo(app, req.body.categoryName);
res.redirect(301, '/groups' + req.body.categoryName);
})
});
.catch(err => {
res.status(400).send("Unable to save to database");
});
});
And if you want to wait for your Car.find() before res.redirect(), you must wait for Car.find() callback...
Welcome to 'callback hell' (you can search on google this).
In recent nodejs version, you can use await/async functionnality to help you with it. See example : https://blog.risingstack.com/mastering-async-await-in-nodejs/
In my node.js app I want to query multiple mongodb collections in a series using mongoose with the async plugin based on result from the first callback in the series.
So far I have this working code but I'm sure there is a better way of doing it async:
router.route('/project/:projectId')
.get(function(req, res) {
var getProjectDetails = function(cb) {
models.Project.findById(req.params.projectId, function(err, project) {
if(err)
res.send(err);
models.Media.find({'project_code' : project.code }, function(err, media) {
cb(null, {'project' : project, 'media': media})
});
})
}
async.parallel([getProjectDetails], function(err, result) {
res.render('details', {data: result});
});
});
As you can see I want to find all entries from the Media collection where project_code equals code from Project collection.
How can I acvhieve this without nesting my mongoose-querys?
Why do you need async in this? I hope this will work.
router.route('/project/:projectId')
.get(function(req, res) {
models.Project.findById(req.params.projectId, function(err, project) {
if(err)
return res.send(err);
models.Media.find({'project_code' : project.code }, function(err, media) {
if(err)
return res.send(err);
return res.render('details', {data: {'project' : project, 'media': media}});
});
});
});
I have this rest API on nodejs as follows
router.route('/api/Customers')
.post(function(req, res) {
var Customer = new Customer();
Customer.name = req.body.name;
Customer.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'Customer created!' });
});
})
.get(function(req, res) {
Customer.find(function(err, Customers) {
if (err)
res.send(err);
res.json(Customers);
});
});
router.route('/api/Customers/:Customer_id')
.get(function(req, res) {
Customer.findById(req.params.Customer_id, function(err, Customer) {
if (err)
res.send(err);
res.json(Customer);
});
})
.put(function(req, res) {
Customer.findById(req.params.Customer_id, function(err, Customer) {
if (err)
res.send(err);
Customer.name = req.body.name;
Customer.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'Customer updated!' });
});
});
})
.delete(function(req, res) {
Customer.remove({
_id: req.params.Customer_id
}, function(err, Customer) {
if (err)
res.send(err);
res.json({ message: 'Successfully deleted' });
});
});
How can I create endpoints for specific fields ? For example if I want to GET results for CustomerName, CustomerZip, etc .. Do I have to create separate end points for each field?
Are you using express.js as framework? In this case you can put optional params in your route, for example:
router.route('/api/Customers/:Customer_id?')
.post(function(req, res) {
...
})
.get(function(req, res) {
...
});
});
in this way :Customer_id will be optional and you can manage logic inside your route.
This is a working example:
app.route('/test/:param1?/:param2?')
.get( function(req, res, next) {
res.json({
'param1' : req.params.param1,
'param2' : req.params.param2
});
});
app.listen(8080);
this route supports:
/test
/test/1
/test/1/2
inside response you can see value of this params, I don't know how pass only param2 without param1.
Im trying to find all documents in a DB using mongoose but I cant do it
I want to do it this way but I don't know what's wrong with it
app.get('/users', function (req, res){
User.find({}, 'name', function(err, user){
if(err){
console.log(err);
}else{
res.render('user-list', {
name : user.name
});
console.log('retrieved list of names' + user.name);
}
})
})
When I use User.findOne({}, 'name', function(err, user){.. I get back the first doc which is what I would expect. Please explain why the code above is not allowing me to get all documents. I feel like I'm using it the right way as show in the mongoose doc
Edit
thanks for help guys
i did like this:
app.get('/users', function (req, res){
User.find({}, 'name', function(err, users){
if(err){
console.log(err);
}else{
res.render('user-list', {
name : users.map(function(doc){
return doc.name + "<br>"
})
});
console.log('retrieved list of names' + users.name);
}
})
})
can some one please help me with getting each name on a new line the "<br>" shows up on the page but it doesn't make a new line "<br>,Joe<br>,mike<br>"
Jade:
extend layout
block content
p list of users #{name}
app.get('/users', function (req, res){
User.find({}, 'name', function(err, users){
if(err){
console.log(err);
} else{
res.render('user-list', users);
console.log('retrieved list of names', users.length, users[0].name);
}
})
});
As said in the comments, find can find many objects, so it returns an array as contrasted with findOne that returns a single object. Adjust for that as above and you should be back on track.
app.get(`/users`, async (req,res)=>{
try{
const users = await User.find({}).exec()
users && res.render('user-list',users)
}catch(error){
res.status(500).json({error})
}
})
//OR
app.get(`/users`, async (req,res)=>{
try{
const users = await User.find({}).exec()
const list = new Array()
for(let row of users){
list.push(`${users.name}<br>`)
}
list ? res.status(200).send(list) : res.status(200).json({message: 'Users list is empty'})
}catch(error){
res.status(500).json({error})
}
})
In second example you send to client a text line!!!