Handlebars Hot Reload - node.js

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.

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.

How to structure external API calls for Node.js, express, ejs routing?

//API Call one
function receiveLocation(){
axios({
"method":"GET",
"url":"https://ip-geo-location.p.rapidapi.com/ip/check",
...
})
.then((response)=>{
return response.data.country.name;
})
.catch((error)=>{
console.log(error)
})
}
//API Call two
//API Call three
console.log(receiveLocation());
app.get("/", function(req,res){
var location = receiveLocation();//
//Then render all the data from my API calls such as location, currency,
//etc. in my landing page. Also use that data on the backend.
res.render("landing",{location:location});
});
I am currently trying to make a website that uses multiple API calls to get information such as location, currency, and other things of a user who loads the website.
I am attempting to receive all the information from the different API calls as I go through the get request route that allows a user to see the landing page. Firstly, I am not even sure if this is allowed. If it is allowed/standard practice, what am I doing wrong in this example. I am attempting to call a function that in the get route to the root page that returns the country of a visiting user. But after doing some console.log() debugging I see that that information is never being received in the get route. Last note: I want to use the info from the API calls both to change what the user sees, and for some calculations that would need to be run on the backend.
If this is not allowed/not standard practice, may someone explain what I should do instead/point in the right direction as to what I should learn to get a better understanding of what I am trying to do
What you are trying at the moment to do is not standard practice, you should lookup MVC for Express,there you will learn how to structure your backend code so that the GET Routes will be used as Views ( these will be your server getting some public files like html,css,javascript that will be passed some information from the Controllers,this is done by using some server-side renders like EJS).
I recommend taking this Udemy course https://www.udemy.com/course/nodejs-the-complete-guide/ for a full understanding,but if you don't have the time,lookup node.js mvc with express, there is plently information about this.

Sending new/mutated data back to the page in the same POST request?

Playing around with React and Node/Express what I have is a form with a POST request that sends some state information back to the server, on the server side I mutate/change the state and then send the state back in the same post without a redirect() or a page refresh.
router.post('/ProjectPost', function(req, res, next){
console.log('postin up');
const transform = req.body.incom += 'neewer'
console.log(transform);
res.json({backAtChew : transform});
})
Is this ok? Is it ideal? Does in only work here because of the small amount of data changes? Is this ok for scaling? Having the least amount of major page changes or refreshes is ideal for a SPA so this doesn't seem bad. In my actual application it will be major SQL calls or Oauthentication or API usage or what have you have you so I wanted to make sure before getting the idea that this was a way to go.
The calls to the server are made with axios.js

SEO for dynamically generated content in SPA (single page application) using node.js + express.js on server side

My client side code is a single page app (written in knockout.js) with its own routing system so when google crawler bot will try to access links (that have nothing to do with requesting new page from back end BUT just a part of client side routing) it will ask server (node.js + express.js) to serve page (for example 'mywebsite/about') and of course server will return 404 because it unawares of client routing system. Here is my current server code:
router.get('*', function(req, res, next) {
res.sendFile(path.resolve('../dist/index.html'));
});
My idea is to define the same routing structure as in a client and pass routs for client routing system in search parameter:
router.get('/about', function(req, res, next) {
res.sendFile(path.resolve('../dist/index.html?tab=about'));
});
then in client side I can catch it in javascript and pick correct route.
Here off course I have another problem - as I understand google bot doesn't run javascript.. but here I can use prerender.io middleware I guess.
1) Is it a right way to go with single page apps with generated content and SEO?
2) How to pass search parameter from express.js?
If you have query strings that Googlebot can use to recall consistent content then you can indicate this in Webmaster:
https://support.google.com/webmasters/answer/6080548?rd=1
Here's an example set up of mine:
Google wants to only index pages that have consistent content. If content varies for each user - then you want to set a rel="canonical" tag on each page indicating where the 'start' would be for this dynamically generated content.
The idea would be to adapt the Webmaster to your app rather than the other way around. Trying to 'trick' the bot can have dire consequences in SEO because Google does have human checkers that occasionally rate domains. If they find inconsistency between the search indexed URL and what they see in their browser, you'll earn a flag from a lazy operator. Here is the handbook operators follow.
Use prerender.io as first middleware of your pipe:
app.use(require('prerender-node').set('prerenderToken', 'YOUR_TOKEN'));
app.get('*', (req, res) => res.render('index.html'));

Can I write middleware to affect the data that is being sent to my template renderer?

I'm writing a web application based on Node.js and Express, using Dust for my templates. My Dust templates all use the same master layout in a separate file. Right now a simple route handler in my app looks like this:
app.get('/', function (req, res) {
res.render('index', {
tenant: req.tenant
});
});
The tenant is being used for rendering some parts of the master layout. Now, I feel like it's pretty inefficient (devtime-wise) to add the 'tenant' variable to the view model in every route handler. In ASP.NET MVC I would write an action filter that runs after every action and adds the tenant to the view model. Is there something similar I can do in Express? Write some connect or router middleware? Or does res.render perform the rendering immediately without any possibility to modify the view model lateron?
And two minutes after posting the message, a nice chap on IRC gives me the answer.
res.locals.tenant = <tenant>
in the middleware does the job.

Resources