Fetch multiple collections with mongoose - javascript

Currently using node.js along with mongoose and express. I have two collections in my MongoDB and I can successfully retrieve data like this:
ActivityList.prototype = {
showActivities: function(req, res) {
point.find({}, function foundPoints(err, items) {
res.render('index2',{title: 'Credits' , points: items})
});
}
These data can be treated in my index.jade like this:
form(action="/asdad", method="post")
select(name = "item[point]")
each point in points
option(value='onlytesting') #{point.Activity}
input(type="submit", value="Update tasks")
As you can see I am using this to fill a drop down menu.. My issue is that i want to fill multiple drop down menus with data from other collections also.
The page is supposed to be my index.jade, such that a user is presented with multiple drop down menus which will be pulled directly from MongoDB.
My app.js calls:
app.get('/', activityList.showActivities.bind(activityList));
That works just fine, but I want to be able to fetch other data also with the "same" get..
Does anyone know how this can be accomplished?
Thanks for any tips

Related

ExpressJS routing don't match the content

I have a NodeJS app that displays some tables from a database. The view engine is ExpressJS.
On the app I have a dropdown list where u can select the table you want to display. The problem is that any given table that I want to display is only accessible through the dropdown, but what I'm trying to do is make them work through URLs.
So for example when u enter an address like: http://localhost:6789/tableOne, I want the table one to be displayed.
But if I load table two from the dropdown, and after that I enter the address I mentioned above, the page displays also table two, so basically is not refreshing with the new data. This makes the app working only through the interface, but I want to share to somebody else the direct link to a table and I can't. (they will receive the last table that was loaded on the app)
To rephrase, take as example an app that displays on the page the route's name. Mine doesn't update.
The routes are dynamically generated and here's an example of the routing that I did:
app.get('/someTables/:' + getNameFromID(selectedID), (req, res) => {
var url = req.url;
for (i in endData) {
if (i.name == url.substr(10)) {
selectedID = i.id;
}
}
res.render('index', { frontData2: endData2, frontData: endData, jsonToDisplayFrontEnd: jsonToDisplay, m1: m1, m21: m21, m22: m22, m1FrontEnd: m1ToDisplay, m21FrontEnd: m21ToDisplay, m22FrontEnd: m22ToDisplay, versionToDisplayFrontEnd: versionToDisplay, titleName: getNameFromID(selectedID), folderPath: getFolderPath(selectedID), folderPath2: getFolderPath2(selectedID) });
});
The function getNameFromID() returns a string.
How can I make this work? Thank you!

Search multiple collections with mongoosastic

In a Node.js application, i am using Mongoosastic to retrieve data from ElasticSearch :
Article.search({
"match_all": {}
}, function (err, results) {
console.log(results.hits.hits);
Post.search({
"match_all": {}
}, function (err, results) {
console.log(results.hits.hits);
return next();
});
});
Here i am making two requests to retrieve data from two different collections. I would like to know if it was the good way to do it ?
Is it possible to search data from the two collections (or multiple collections) in one single request ? (with the multi search API for example, but with Mongoosastic).
Thank you.
Looks like we can't do it with Mongoosastic.
In fact, the project define itself in the GitHub page as :
a mongoose plugin that can automatically index your models into
elasticsearch
So i use it to define my indexes, but to do search queries it works fine with the official javascript client.
The same question here : https://github.com/mongoosastic/mongoosastic/issues/41

Display data from database (using mongodb) in hbs/html file Node.Js

I started studying node.js, and now I'm trying to do a "Todo-App".
I'm trying to find the best way to transfer data from my database (using mongodb) into my hbs files, so I could display it.
From the server.js -> server to the hbs -> client (correct to me if I'm wrong please, by assuming that server.js is the server of course and the hbs file is the client)
So, I succeeded to do it by passing an array.
but when I'm trying to display in html desing, it just looking bad.
The code:
app.get('/allTasks',(req,res)=>{ //get (go to) the allTasks (hbs file)
Todo.find().then((todos) => {
console.log(todos);
var arrayOfTodos = [];
todos.forEach(function(element){
console.log("\n\n\n\n\n elemnt details: ",element.text + "\n",element.completed+"\n");
arrayOfTodos.push(element.text,element.completed);
});
res.render("allTasks.hbs", {
pageTitle: "Your tasks: ",
todos: arrayOfTodos
});
});
});
The result is:
You can see a picture
As you can see, its just looking bad... cause it just display an array,
an I want to display each task seperately.
Any tips?
Thanks a lot,
Sagiv
Instead of using push just do:
Todo.find().toArray(function(err, result){
arrayOfTodos = result;
})
Once you have your array, the design got nothing to do with mongodb. You will need to learn how to use your render technology. You need to touch your html template, so you should start by posting that.
The problem solved.
I just had to learn how to handle the data in the hbs side.
so the code is: (in hbs)
{{#each todos}}
{{missionNumber}} <br>
{{text}}<br>
completed = {{completed}}<br><br>
{{/each}}
as you can see, the each is a loop , that pass on the todos parameter (my array)
and i just have to display the data in the way i want it to be displayed.
thanks for your help.

Node.js - how to implement api/:product_url

I am new to node.js and I am using Yeoman to fetch a product details from the list of products. I am getting data from a triple store database and converting to json. The only unique ID is in the form of URL with an hash encoded at last.
In demo.controller.js:
exports.index = function(req, res) {
res.json(response);
}
In index.js:
var controller = require('./demo.controller');
var router = express.Router();
router.get('/', controller.index);
module.exports = router;
Here, response output is the following json structure for URL/api/product_list:
[{
"url":"http://example.com/demo/32b9jkd902n2"
"product":"stack",
"name":"test",
"price":"233"
}, {
"url":"http://example.com/demo/5nf9djdkdks0"
"product":"flow",
"name":"dev",
"price":"433"
}]
Now, I want to get details of each product. something like URL/api/product_list/:product_url ?
Basically, when I access url with product_url from the list of products, I should be able to get the product details.
Can someone help me in implementing the URL with /api/product_list/:product_url with an output of single product?
So, as there is no other unique identifier besides the URL you could to one of the following:
Parse unique ID from the url to /api/product_list as id to the output and use that - /api/product_list/:id
Generate a hash (md5, sha1) of the whole url to the output as id and use that as an unique id.
Note: never used Yeoman before, so I don't know if you have some limitations from there.
I think /api/product_list/:url will not fly, and if it does, it sure will look ugly.

Mongo check if a document already exists

In the MEAN app I'm currently building, the client-side makes a $http POST request to my API with a JSON array of soundcloud track data specific to that user. What I now want to achieve is for those tracks to be saved to my app database under a 'tracks' table. That way I'm then able to load tracks for that user from the database and also have the ability to create unique client URLs (/tracks/:track)
Some example data:
{
artist: "Nicole Moudaber"
artwork: "https://i1.sndcdn.com/artworks-000087731284-gevxfm-large.jpg?e76cf77"
source: "soundcloud"
stream: "https://api.soundcloud.com/tracks/162626499/stream.mp3?client_id=7d7e31b7e9ae5dc73586fcd143574550"
title: "In The MOOD - Episode 14"
}
This data is then passed to the API like so:
app.post('/tracks/add/new', function (req, res) {
var newTrack;
for (var i = 0; i < req.body.length; i++) {
newTrack = new tracksTable({
for_user: req.user._id,
title: req.body[i].title,
artist: req.body[i].artist,
artwork: req.body[i].artwork,
source: req.body[i].source,
stream: req.body[i].stream
});
tracksTable.find({'for_user': req.user._id, stream: req.body[i].stream}, function (err, trackTableData) {
if (err)
console.log('MongoDB Error: ' + err);
// stuck here - read below
});
}
});
The point at which I'm stuck, as marked above is this: I need to check if that track already exists in the database for that user, if it doesn't then save it. Then, once the loop has finished and all tracks have either been saved or ignored, a 200 response needs to be sent back to my client.
I've tried several methods so far and nothing seems to work, I've really hit a wall and so help/advice on this would be greatly appreciated.
Create a compound index and make it unique.
Using the index mentioned above will ensure that there are no documents which have the same for_user and stream.
trackSchema.ensureIndex( {for_user:1, stream:1}, {unique, true} )
Now use the mongoDB batch operation to insert multiple documents.
//docs is the array of tracks you are going to insert.
trackTable.collection.insert(docs, options, function(err,savedDocs){
//savedDocs is the array of docs saved.
//By checking savedDocs you can see how many tracks were actually inserted
})
Make sure to validate your objects as by using .collection we are bypassing mongoose.
Make a unique _id based on user and track. In mongo you can pass in the _id that you want to use.
Example {_id : "NicoleMoudaber InTheMOODEpisode14",
artist: "Nicole Moudaber"
artwork: "https://i1.sndcdn.com/artworks-000087731284-gevxfm-large.jpg?e76cf77"
source: "soundcloud"
stream: "https://api.soundcloud.com/tracks/162626499/stream.mp3? client_id=7d7e31b7e9ae5dc73586fcd143574550"
title: "In The MOOD - Episode 14"}
_id must be unique and won't let you insert another document with the same _id. You could also use this to find the record later db.collection.find({_id : NicoleMoudaber InTheMOODEpisode14})
or you could find all tracks for db.collection.find({_id : /^NicoleMoudaber/}) and it will still use the index.
There is another method to this that I can explain if you dont' like this one.
Both options will work in a sharded environment as well as a single replica set. "Unique" indexes do not work in a sharded environment.
Soundcloud API provides a track id, just use it.
then before inserting datas you make a
tracks.find({id_soundcloud : 25645456}).exec(function(err,track){
if(track.length){ console.log("do nothing")}else {//insert}
});

Categories

Resources