Node & Mongoose - Loading correct collection after clicking a link - node.js

I need help!! I have this code:
router.get("/campgrounds", function(req,res) {
Campground.find({}, function(err, campgrounds) {
if(err) {
console.log(err);
} else {
res.render("campgrounds/index", {campgrounds: campgrounds});
}
});
});
Unfortunately I couldn't find any good examples online.
I wanted index to load different mongo collections after clicking on the link that leads to /campgrounds which I want to change to /:locations_id.
The main page will have 3 links to location1, location2 and location3 respectively.
Is there a way to load a different collection (location 1, 2 or 3) at /:locations_id depending on the link clicked before?
My idea was to use req.params.locations_id and maybe append some info on the clicked link and use it in an if statement in order to load the correct collection.
Thank you very much for your help and I apologize for the extremely conceptual question.

Hmmm, I guess you can pull a trick.
//Put every collection in an array
var collections = [
Campground,
Collection2,
Collection3
];
//When user visits: example.com/campgrounds/1
router.get("/campgrounds/:locationId", function(req,res) {
//Parse the index from the URL
var locId = parseInt(req.params.locationId);
//Make sure that we aren't blown up :)
if(isNaN(locId) || locId > 2) {
//Default collection's index - which is Campground in this example
locId = 0;
}
//Match the given collection by its index and return it
collections[locId].find({}, function(err, campgrounds) {
if(err) {
console.log(err);
} else {
res.render("campgrounds/index", {campgrounds: campgrounds});
}
});
});

Related

Global search is not working in DataTable when server side is enabed in NodeJs

I am trying to get form data from MongoDB server and showing it into data table using nodeJs.I successfully have done server-side pagination using npm Paginate v-2 plugin. But now the searching is not working. Below is my NodeJs and javascript files code. Please help me for searching.
NodeJs code
app.get('/gettable',(req,res)=>{
console.log(req.query);
user.paginate({},{
page:Math.ceil(req.query.start / req.query.length) + 1,
limit:parseInt(req.query.length)
},function(err,result){
var mytable = {
draw:req.query.draw,
recordsTotal:0,
recordsFiltered:0,
data:[],
}
if(err) {
console.log(err);
res.json(mytable);
} else {
if(result.totalDocs > 0) {
mytable.recordsTotal = result.totalDocs;
mytable.recordsFiltered = result.totalDocs;
for(var key in result.docs) {
mytable.data.push([
result.docs[key]['name'],
result.docs[key]['lastname'],
result.docs[key]['email'],
result.docs[key]['pass'],
result.docs[key]['birthdate'],
result.docs[key]['zipcode'],
result.docs[key]['phonenumber'],
]);
}
}
res.json(mytable);
}
});
DisplayTable.Js code
$(document).ready(function(){
$('#example').DataTable({
"processing": true,
"serverSide": true,
"ajax": "http://localhost:8080/gettable"
});
})
As I said, I am successfully getting data from a server and showing into data table with server-side pagination but searching is not working but in searching div whatever I search, I am getting that value in search array, like this
search: { value: 'svs', regex: 'false' },
_: '1548653540009' }
But its not implementing in datatable to filter columns.
As I said in the comment that search will not work out of the box when server side is enabled in DataTable, it is because now the whole functionality, whether sorting, paging, limit, and search has to be implemented in the server. DataTable will only send the parameter needed for doing the functionality. Following is the code just for your reference, it is not tested and you may get an error also. You may get inputs from the following code. Feel free to edit the following code if in case of getting errors so that it can help future readers.
app.get('/gettable',(req,res)=>{
console.log(req.query);
var query = {},
// array of columns that you want to show in table
columns = ['name', 'lastname', 'email', 'pass', 'birthdate', 'zipcode', 'phonenumber',];
// check if global search is enabled and it's value is defined
if (typeof req.query.search !== 'undefined' && req.query.search.value != '') {
// get global search value
var text = req.query.search.value;
// iterate over each field definition to check whether search is enabled
// for that particular column or not. You can set search enable/disable
// in datatable initialization.
for (var i=0; i<req.query.columns.length; i++) {
requestColumn = req.query.columns[i];
column = columns[requestColumn.data];
// if search is enabled for that particular field then create query
if (requestColumn.searchable == 'true') {
query[column] = {
$regex: text,
};
}
}
}
user.paginate(query,{
page:Math.ceil(req.query.start / req.query.length) + 1,
limit:parseInt(req.query.length)
},function(err,result){
var mytable = {
draw:req.query.draw,
recordsTotal:0,
recordsFiltered:0,
data:[],
}
if(err) {
console.log(err);
res.json(mytable);
} else {
if(result.totalDocs > 0) {
mytable.recordsTotal = result.totalDocs;
mytable.recordsFiltered = result.totalDocs;
for(var key in result.docs) {
var data = [];
for(var column in columns) {
data.push(result.docs[key][column]);
}
mytable.data.push(data);
}
}
res.json(mytable);
}
});

Searching in Datatable using Paginate-v2 plugin

I am trying to connect MongoDB with nodejs and fetching data from MongoDB server and showing into the HTML page which has Datatable. So the Fetching of data is occurring on the server side.I am successfully getting the data from MongoDB and paginate them with the help of Paginate-v2 plugin. But now the search is not working of datatable. Pagination -v2 has one function name populate to do searching in datatable but it's not working for me. Please help me with this. Below is my Node JS code.
NodeJs code
app.get('/gettable',(req,res)=>{
console.log(req.query);
user.find({}).populate({
select:'name',
match: { 'name': 'Graiden Waller' }
}).exec((err, user) => {
console.log(user.name) ;
}).paginate({},{
page:Math.ceil(req.query.start / req.query.length) + 1,
limit:parseInt(req.query.length),
populate:{
match:{
name:'Graiden Waller'
}
}
},function(err,result){
console.log(result);
var mytable = {
draw:req.query.draw,
recordsTotal:0,
recordsFiltered:0,
data:[],
}
if(err) {
console.log(err);
res.json(mytable);
} else {
if(result.totalDocs > 0) {
mytable.recordsTotal = result.totalDocs;
mytable.recordsFiltered = result.totalDocs;
for(var key in result.docs) {
mytable.data.push([
result.docs[key]['name'],
result.docs[key]['lastname'],
result.docs[key]['email'],
result.docs[key]['pass'],
result.docs[key]['birthdate'],
result.docs[key]['zipcode'],
result.docs[key]['phonenumber'],
]);
}
}
res.json(mytable);
} });
Whenever I use populate, it showing me this error Cannot read property 'count' of undefined I don't know what should I write for searching in a data table.Please help me for this issue.

Loopback Find then update attribute or delete by id

Been trying to find samples usage for some of the static methods for a persistedModel in Loopback.
https://apidocs.strongloop.com/loopback/#persistedmodel-prototype-updateattribute
it just says:
persistedModel.updateAttributes(data, callback)
But how you I choose the which record I want to update? this is not working for me.
var order = Order.setId('whateverrecordId');
order.updateAttributes({name:'new name'},callback)
Loving loopback.. but their doc, sucks.. :(
You can use those on event listener like AfterSave
example:
Model.observe('after save', function(ctx, next) {
ctx.instance.updateAttribute(fieldname:'new value');
next();
});
1- What you did was right but i do not advise this method it's used for instance methods and generally to update fields like date for all the collection that you have so you don't need an id for it.
But you can try to make an array containing data to update containing also the ids and then make a comparison to fill in data for the ids that you have. (in #dosomething)
order.find().then(function(orders) {
orders.forEach(function(element) {
order.setId(element.id);
#DoSomething
order.updateAttribute({new: data}, function(err, instance) {
console.log(instance);
})
});
})
2- You can use updateAll to update one or many attribute.
PersistedModel.updateAll([where], data, callback)
var Updates = [{id : 1, name: name1}, ...]
Updates.forEach(function(element) {
order.updateAll({id : element.id}, {name :element.name}, function(err, count) {
if (err) {
console.error(err);
}
console.log(count); // number of data updated
})
})

Trying to understand mongodb's findOne function's behaviour and why it's causing the following issue

What I am trying to do here is find a user by id and if the user is not found then I am adding it to the collection. However, if found, I simply want to push a new product into the existing user's document.
The issue here is the following if statement that is inside a for loop:
for(var i=0; i < data.products.length; i++) {
console.log("Product
found:"+!data.products[i].product.equals(req.body._id));
//if the requested product is not found
if(!data.products[i].product.equals(req.body._id)){
data.products.push({product: req.body._id, isAdded: true,
quantity:1});
}
console.log("Adding product.....");
}//for loop
It seems that the first iteration find the condition true even though I already have a product with the same id exists. It should be false as long as the id exists in my document. Would anyone be able to explain this behavior of Mongoose please?
The console.log inside the for loop is returning the following results:
Product found:true
Adding product.....
Product found:false
Adding product.....
Product found:false
Adding product.....
Product found:false
Adding product.....
api.post('/me/cart', wagner.invoke(function(Cart) {
return function(req, res, next) {
console.log("new post request"+ req.headers['usr'] );
Cart.findOne({userId: req.headers['usr']},
function(err,data){
if(err){
throw err;
}
console.log("found this..."+ (!data));
//if No user is found add a new cart
if(!data && data.length < 0){
var cart = new Cart();
cart.userId = req.headers['usr'];
cart.products.push({product: req.body._id,
quantity:1, isAdded:true});
cart.save(function(error, data) {
if (error){
return res.
status(status.INTERNAL_SERVER_ERROR).
json({ error: error.toString() });
};
return res.json({ product: data });
});
}
//if user is found updated found users cart
else if (data){
for(var i=0; i < data.products.length; i++){
//if the requested product is not found
if(!data.products[i].product.equals(req.body._id)){
data.products.push({product: req.body._id,
isAdded: true, quantity:1});
}
console.log("Adding product.....");
}//for loop
data.save(function(err, updatedCart){
if(err)
throw err;
console.log(updatedCart);
return res.json(updatedCart);
});
}//else if
});
};
I was doing it wrong. Basic for loop fundamentals lol It is obvious that the condition would be true every time it does not find the product id and so will execute the push statement every time it does not find the id. Which will cause it to create duplicate data in the database. The solution was to simply add boolean flag inside the if condition and turn it on if it does not find a value and then use that flag to save and push a new product.
P.s Was stuck with the missing semicolon type of issue for 3 days lol Only because i forgot about minor for loop fundamental. Anyways, mistakes are what teach us the best :D Enjoy.

How to query data from different collections and sort by date?

I stumbled upon problem that my search results are of a mixed data, which is located in different collections (posts/venues/etc), currently Im doing separate requests to retrieve this data, but its obviously sorted among its types (posts array, venues array)
How can I query multiple collections (posts/venues) and sort them by date/any other parameter (via mongoose)?
or maybe there is a better solution?
Thanks
I believe its not possible with Mongoose, you can in the meanwhile do something like this:
var async = require('async');
function getPosts(cb) {
Post.find({"foo": "bar"}, function(err, posts) {
cb(err, posts);
})
}
function getVenues(cb) {
Venue.find({"foo": "bar"}, function(err, venues) {
cb(err, venues);
})
}
async.parallel([getPosts, getVenues], function(err, results) {
if(err) {
next(err);
}
res.send(results.sort(function(a, b) {
//if default sorting is not enough you can change it here
return a.date < b.date ? -1 : a.date > b.date ? 1 : 0;
}));
});
This code assumes you are inside an express route and that both Posts and Venues have a common attribute; date. In case you named these dates attributes differently you would have to improve the sort algorithm.

Resources