Serving Dynamic Webpages with Node.js - html

I am having a hard time understanding how exactly node.js serves dynamic content.
So let's say we have the following code that renders a home page:
var express = require('express'),
app = express();
app.get('/', function(req,res){
res.render('home.html');
});
However, let's say this home page was supposed to be a user profile in which you are pulling user information from a database, which results in code:
var express = require('express'),
mongoose = require('mongoose'),
app = express();
mongoose.connect('mongodb://localhost/ExampleDB');
app.get('/:id', function(req,res){
User.findOne({_id: req.id}, function (err, user){
var name = user.name;
var profilePic_uri = user.profilePic_uri;
res.render('home.html');
});
So, ideally home.html is just a template page, in which you set maybe the user's profile picture, their name, etc in the route handler. Right, because the idea behind node, is that this app.js should be able to handle pulling the dynamic content from a database at run time. Where I am having trouble is understanding how exactly rendering dynamic pages work with node. The html page is a static page. You can't really render a php or a asp page because, well, that doesn't really make sense does it?
Which leaves me with the question, how is it done?

If you add...
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
...after app=express() has been done then it will now default to the Jade rendering engine if you don't use an extension. Then in your router:
app.get('/', function(req,res){
res.render('home', {
var1: 'val1',
var2: 'val2'
});
});
You'd need to add Jade to your project's package.json file in the dependencies:
"jade": "~1.9.1",
...and then "npm install" in your folder to bring that in.
Then you'd need a file named /views/home.jade with the contents:
doctype html
html
body
p Var1 is #{var1}
p Var2 is #{var2}
You should see--when you visit your home page--that the values have been passed to the Jade rendering engine and expanded in place in the template as 'val1' and 'val2', respectively.

In your case the page is static. Here comes in play template engines (view engines), with this you can render the content of the page dynamic.
Some of the template engines that I remember right now are vash (it's like razor syntax from MVC, I love it) and jade. There are more of them.
Note: You can find in the links I provided how to integrate them with express.

What you are actually asking is not, how it works in Node, but how Express renders templates. Once you understand that you're actually using a feature of the express module, you're probably more aware of what you need to search for to get the correct documentation.
In short: Express features a template rendering engine that does the job for you, very much similar to what ASP or PHP do.
To get to know Node, I'd advise to try to build something without all the libraries first, just to get to know the platform, and to understand why it's feasible to use such libraries or frameworks (such as express).

Related

Is it not proper to use the send method to return HTML? Express

I am playing with express, in the past I have used echo with PHP to render out lines of html. In node/express I can add html to a variable and use res.send to return html. That way I can run loops and other things right in the function returning that route. Is this method bad practice? Below I have an example that counts to four.
var router = express.Router();
let a = (req, res, next) => {
let send = `<html>`;
for (let i = 0; i < 5; i++) {
send += `${i}`;
}
send += `</html>`;
res.send(send);
//res.download(filepath)
}
router.get('/', [a]);
module.exports = router;
I think this is a way to go about express router but it's probably not the easiest and it would cause a lot of code on your router page. It all depends on how large and scalable you want your project to be. If you are looking at doing a smaller project then this would work but if you were doing something a little larger e.g. e-commerce site then I would say put your html files in a separate folder and create a views directory for express. I would also suggest using an open source JavaScript Framework such as ReactJS, Vue, or ejs to name a few. You would have to do more code to your express server by adding views as seen in this link
Adding views in express
So instead of sending the html you would do something like res.render('/home'); if that is what you called your home page in your views file.
If that didn't answer your question please let me know.

How to resolve dynamic routes on client side in Next js framework

I am currently on Next js using full static generation, as I want to serve all my pages from the S3 + cloudfront (no server involved). Next js has good support for this except when it comes to dynamic pages (ex: /posts/:id). All the framework features to solve this type of scenario involve either rendering all passible pages at build time (which is not viable) or having a server to render these pages that have dynamic routes (making, therefore, the site an hybrid app).
To continue to be full static I need to have a way around this.
In create react app one could use the react-router and resolve the routes on the client side, which is exactly what I want to do for the dynamic routes. But I as far as I know next js and the react-router are not compatible, so apparently that is not an option.
Based on what I know, I think Dynamic Route on SSG is supported. Dynamic route feature is independent of getServerSideProps or getStaticProps. you can just use next/router to get the param you need and render your page accordingly.
Here is the official example.
import { useRouter } from 'next/router'
const Post = () => {
const router = useRouter()
const { pid } = router.query
return <p>Post: {pid}</p>
}
export default Post
Reference
https://nextjs.org/docs/routing/dynamic-routes

How to check Speed(performance) view engines [pug/ejs/html]

I'm trying to make Web-Server with Node.js.
First of my project using pug for view engine.
But, Web-Designer gives me html, but it's syntax is too different from pug.
So, I want to change my project as html or ejs. (I think ejs is similar to html)
(I don't know how to set view engine ~~.html, so I use ejs)
(But I'm not sure this way is right, under paragraph)
First, I generate new repository with express --no-view.
I set view engine in app.js like under,
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.engine('html', require('ejs').renderFile);
Now, I have some question for speed(performance) between [EJS, PUG, pure HTML].
I think render speed is HTML > EJS > PUG, but I have no ideas for check this performance.
I need advice. Any Guess, Link, Answers can help me.
Thanks to read my question.
Short Answer:
EJS : 900-1200 request per second
HTML: 6000 request per second and 12000 with some customizations
Long Answer:
I made a simple test and I've got with express about 6000 request in a second with pure HTML and got about 12000 request per second by storing the HTML in a variable and send it to the client and tried with ejs I've got 900-1200 request per second
But the results may change by the way your code works and how your html/ejs file is written could change the results

Polymer - url rooting after deployment to subdirectory

Ive created a basic Polymer app from the starter kit (via Yeoman). I've today deployed it to the 'sandbox' on my domain and am getting a strange routing issue. The app is essentially a feed reader.
View app here
When I first visit the app I'm given a blank page whereas locally I'm taken straight to the feed. When clicking on 'News Feed' I'm then taken to the feed as expected.
I've added a route for the path of the domain structure as below but this did not fix it.
You can view the full code of the project here.
routing.html
page('/', function () {
app.route = 'home';
});
page('http://purelywebdesign.co.uk/sandbox/f1feedreader/', function () {
app.route = 'home';
});
I've also tried:
page('/sandbox/f1feedreader/', function () {
app.route = 'home';
});
Any help much appreciated.
Page.js allows you to configure the base path:
page.base('/sandbox/f1feedreader/');
or just use window.location if you don't want to tie is to that specific deployment.
page.base(window.location.pathname);
This is an issue with the way the router page.js works. I assume you were testing with gulp serve (which creates a server and sets the web app base url of "/" to be localhost:3000/). The way you're currently setting your page.js routes is that it's looking exactly after the domain name and not at the "root" of the web directory.
In your case page.js is looking at everything after http://purelywebdesign.co.uk/ (meaning all your routes include should start from sandbox/f1feedreader instead of just /f1feedreader).
The documentation for page.js https://visionmedia.github.io/page.js/ says that it uses regular expressions so you could also update the strings.

Pre-populating HTML/Jade from Express/node.js web app

I have a web app that is built using Express for node.js. I'm using Jade template files for the HTML displays. In one of these displays I'd like to have the various fields pre-populated with data. The data is being stored in a mongodb session store, as well as in a separate collection in the db. I'd prefer to use the session data to pre-populate these fields in the HTML/Jade displays. How can I go about doing this (if it's possible)?
Add the defaults to res.locals and then set the input elements value attribute in jade.
//node.js
app.get('/', function(req, res){
// Sorry I am unfamiliar with Mongo, not sure the syntax...
mongo.get('defaults', function(err, body){
res.locals.dName = body.defaultName;
res.locals.dFoo = body.defaultFoo;
res.render('myTemplate');
});
});
//myTemplate.jade
!!!
html
body
form(action='/form', method='post')
input#formName(name='name', value=locals.dName)
input#formFoo(name='foo', value=locals.dFoo)
I figured it out by using res.render() from the Express API to do this. I will credit Plato with the answer though because his also seems to be correct and he's a nice man for answering my question.
exports.viewProfile = function(req, res) {
res.render('viewProfile', {username: req.session.user, firstname: req.session.firstname});
}