Generate Express Routes Dynamically from MongoDB Data which changes every few Minutes - node.js

I want to create a web page that dynamically renders data from mongoDB.
I am crawling articles on the internet and then saving data related to that in a MongoDB.
Now I want to create dynamic routes within express (e.g. page/:word), where word is a word taken from the crawled articles. If you use that route you get some information and statistics about the word (e.g. when it's used most)
The Problem I am having now is, that once i started my NodeJS Express Server the routes aren't updatet because once the data is loaded from the MongoDB it's not updatet later, when there is for example a new word in the database.
Is there any way to update these routes dynamically when I change data in the MongoDB ?
Btw: I am Using Handlebars to render the webpage, would all of that be easier with Angular ?
Thank you so much for your help!

You could check the database for each request, to see if the word can be found in the database:
app.get('/page/:word', (req, res) => {
collection.find({ word : req.params.word }).toArray().then(results => {
if (results.length) {
...word found...
} else {
...word not found...
}
});
});

Related

Passing data to dynamic page in node.js without templating engine

I am building a blogging website with node/express.js and mongodb. Now, I want to view individual blog so I created an endpoint of '/articles/:id' so I can only display that particular blog details.
But the problem is how do I show the blog related information in an html page, how do I send that information to frontend ? Like I can't even do a fetch on the '/articles/:id' endpoint because the id would change depending on the specific blog.
One solution you might say is that to use a templating engine but I build the whole thing up till now without templating engine and also I want to know how to do it without a templating engine.
This is my code for individual article. Here I am fetching the blog data from mongodb database and sending it via res.json
app.get('/articles/:id', (req, res) => {
ArticleModel.findById(req.params.id).then(article => res.json(article));
});
Is it possible to so without any templating engine at first place ?
In my view You have two alternatives :-
-> you can send HTML code using res.send like this.
app.get('/articles/:id', (req, res) => {
const city="Londan";
const country="England";
const temp=24;
res.send("<h1>Hello, The temperature in "+city+","+country+" is "+temp+"</h1>");
});
-> Use a library which replaces template engine or in other words which t can do HTML and DOM manipulation like jsdom, cheerio, plates.(haven't tried this personally) because I have always use template engine because it helps me to separate service side code and client side code.
This answer talks in more details about https://stackoverflow.com/a/10114041/13126651.
But my recommendations would be to use template engine for it will simplify your most of the work, there are lof of great options like ejs and my personal favourite is handlebars.

MongoDB, Node, Express, EJS - Pass a array/variable from backend to frontend (from route to client)

I've been trying to figure out a better way to push a variable from the backend to the frontend. Right now I do something like this.
I have a MVC-pattern, so when hitting the route
app.get('/fil', middleWare.isLoggedIn, user.fil)
... trough node does some querying the DB, and pass on the data.
exports.fil = async (req, res) => {
try {
faktura = await Lan.find().populate('client', 'namn kundnr')
res.status(200).render('pages/createInvoice', {
faktura: faktura
});
} catch (err) {
return res.status(500).send({
message: err.message || "Some error occurred while retrieving datas."
});
};
};
... it generates the page, with the help of EJS (i love EJS) and then pass it on to the client/user.
And in the .ejs-file that is served to the client/user I add the following
<script>
var fakturor = <%- JSON.stringify(faktura) %>;
</script>
which then means that I use up the variable and work with it with JS.
And this is where my question pops up. Is this a good way to do it or is there any other way to handle it?
I guess one idea is to let the user to query the DB straight from the page, but in my case I believe it wouldn't actually be better for the user to do so (the user will reieve like 100 different rows that they will be able to filter and then download a file of)
But is there any other ways I could do this without the script-tag? Like i said, I guess a ajax-call from JS/the client could be used but could you do it any other way? Can EJS do it any other way?
ejs is used for static pages mainly, if you want to build a dynamic page I would look for a single page application framework like angular and react.
if you still want to use ejs you can use ajax call to the server to load a variable from the DB.
I would never query directly from Front end to DB because then you are not controlling the security of the server, always go through the BE.
also try to think if you really need a variable in the front end, can you solve your problem using rendering only?

Problem integrating Angular SPA and mongodb in heroku

I am creating a simple app using angular and I am trying to use mongodb to save my data. So far I managed to create my SPA with angular and deploy it to heroku adding the server.js file. My problem starts when I tried to connect mongodb.
Currently I was serving my page using
app.get('/*', function(req,res) {
res.sendFile(path.join(__dirname,'/dist/showoff/index.html'));
});
Inside index.html I am calling <app-root> and my application has two routes: /display and /control
I then realized I have to add some more routes to save and read from my database through a service, so I had to add things like:
router.route('/players').get((req, res) => {
Player.find((err, player) => {
if (err)
console.log(err);
else
res.json(player);
});
});
Problem is that I cant reach those routes since I have already one with /*. I tried writing this other routes on top as I figured it might take the first it finds but its not working and I am always redirected to my index.html
My question is:
Is there a way to deploy my SPA like this and still use mongo? or do I need to somehow restructure everything since my approach isn't right?
You can find my whole code here if needed GitHub code
In case it helps anyone I did the following. Not sure if its the best way to go but it worked.
I divided my /* route as follows
app.get('/display', function(req,res) {
res.sendFile(path.join(__dirname,'/dist/showoff/index.html'));
});
app.get('/control', function(req,res) {
res.sendFile(path.join(__dirname,'/dist/showoff/index.html'));
});
And continue to add handlers for other routes there, which manage the requests to write and read from the database.

Handlebars Hot Reload

I'm building a betting web application through Node, Handlebars, Express and Mongo. One of my key requirements is to have live updates of betting odds as they change in the database. Currently, the data is rendered on a Handlebars template via Mongoose queries. Here is a sample where 10 'To Win' markets are rendered on the homepage, as well as carrying over the user's session details:
app.get('/', function(req, res, next){
Market.find({"marketname" : 'To Win'}).limit(10)
.then(function(doc){
res.render('index', {items: doc, user: req.user});
});
});
My problem is that odds can fluctuate regularly and I have no way to trigger a re-render with the updated data without either refreshing the page or navigating to another link and back to the given page. If any more information is required I'll edit the post appropriately.
You can use web sockets to handle the real time aspect of your app. There are a number of good libraries and articles on the web that can help you with implementation.
If you're flexible about which database to use, you could also look into a push based database such as RethinkDB.

How get data from mongodb into react router to render on page

I have an existing blog and I want to move to react. My production blog uses node, express, and mongodb. I followed this guide to get up and running with react. I think I can use the pages I've setup to grab data from mongo with a request like https://domain.com/api/all-documents for the homepage. How can I add an API request to the react router in the app.get('*',(req, res) section from the guide's app-server.js file?
I want to add something like:
const db = require('monk')('localhost/myDB')
const documents= db.get('documents')
db.close()
app.get('/api/all-documents',function(req,res){
documents.find({}, {}, function(err, docs) {
res.json(docs);
});
});
Then in my react pages I can use the JSON data to add content to the page ... right?
Thanks!

Resources