res.render in Express - html

I am new to ExpressJS
index.js
res.render('welcome', { name : "bleh"});
welcome.html
<html lang="en">
<body>
<h1>Welcome</h1>
<script>
console.log(name)
</script>
</body>
</html>
How do I get the value of "name" in my HTML page?

You can't really pass variable to html with res.render.
You should consider using a template engine (there are many of them : pug, handlebar, nunjucks, ejs .... it's up to you to choose). In this case, you'll be able to pass variable with res.render (#cobaltway sended you the docs in comments)
Another options is to make ajax query in your welcome.html to your express server (which will work as an API).
So you'll have this in your index.js res.send({name : "bleh"});

Related

How to include a code fragment from a text file into html?

Is there a simple way (or what could be the simplest way) to include a html-code fragment, which is stored in a text file, into a page code?
E.g. the text file fragment.txt contains this:
<b><i>External text</i></b>
And the page code should include this fragment "on the fly". (Without php ...?)
The Javascript approach seems to be the preferred one. But with the examples below you possibly can get problems with cross origin requests (localhost to internet and vice versa) or you can have security problems when including external scripts which are not served via HTTPS.
An inline solution without any external libraries would be:
<!DOCTYPE html>
<html>
<body>
<div id="textcontent"></div>
<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
document.getElementById('textcontent').innerText = xhttp.responseText;
};
xhttp.open("GET", "content.txt", true);
xhttp.send();
</script>
</body>
</html>
Here you need a file content.txt in the same folder as the HTML file. The text file is loaded via AJAX and then put into the div with the id textcontent. Error handlings are not included in the example above. Details about XMLHttpRequest you can find at http://www.w3schools.com/xml/xml_http.asp.
EDIT:
As VKK mentioned in another answer, you need to put the files on a server to test it, otherwise you get Cross-Origin-Errors like XMLHttpRequest cannot load file:///D:/content.txt. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.
You need to use Javascript to do this (or perhaps an iframe which I would avoid). I'd recommend using the JQuery framework. It provides a very simply DOM method (load) that allows you to load the contents of another file into an HTML element. This is really intended for AJAX calls, but it would work in your use case as well. The fragment.txt would need to be in the same server directory as the html page (if it's in a different directory just add on a path).
The load method is wrapped in the $(document).ready event handler since you can only access/edit the contents element after the DOM (a representation of the page) has been loaded.
Most browsers don't support local AJAX calls (the load method uses AJAX) - typically the HTML and txt files would be uploaded to a server and then the html file would be accesed on the client. Firefox does support local AJAX though, so if you want to test it locally use Firefox.
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>
<script>
$(document).ready(function() {
$("#contents").load("fragment.txt");
});
</script>
</head>
<body>
<div id="contents"></div>
</body>
</html>
With javascript. I use it.
Example:
<!DOCTYPE html>
<html>
<script src="http://www.w3schools.com/lib/w3data.js"></script>
<body>
<div w3-include-html="content.html"></div>
<script>
w3IncludeHTML();
</script>
</body>
</html>

How to safely pass Redux store from the server to the client

I am working on a React app with server-side rendering. The app uses Redux for state management and Redux Saga for async actions. In pseudocode, what I am doing on the server side right now is:
1) initialize Redux store and run Redux saga on it
2) wait until all necessary data is fetched
3) render React component to string
4) send rendered React component to the client
(along with the populated store for rehydration on the client side)
My problem is with step 4. Right now, I am passing the rendered React component and the store to an ejs view that looks roughly like this:
<html>
<head>
<meta charset="utf-8">
<title>Test</title>
<link rel="stylesheet" type="text/css" href="/styles.css">
<script>
var __data = <%-JSON.stringify(store) %>;
</script>
</head>
<body>
<main><%- app %></main>
<script type="text/javascript" src="/vendor.js"></script>
<script type="text/javascript" src="/bundle.js"></script>
</body>
</html>
(in the code above, app is the rendered React component, and store is the Redux store)
Trouble is, the above code, specifically
<script>
var __data = <%-JSON.stringify(store) %>;
</script>
does not escape html, so if my store contains a string with the <script> tag, it will be valid html, and opens the app to XSS attacks.
If instead of <%- %> use <%= %> like so: var __data = "<%= JSON.stringify(store) %>";, I get a string that is invalid JSON:
"{"greetingReducer":{"message":"Hello world!"} etc.
which I am not sure how to transform back to valid JSON.
So my question (silly as it may seem) is: what’s a proper way of passing a Redux store (HTML-escaped string of a JSON object) in the HTML template to the client and how to transform that string back to a JavaScript object on the client.
You can try serialize-javascript if you're ok with including another module to do this. It has support to escape harmful HTML strings.

Browser crashes on angularjs $http.get

I'm working on a template system with angularJs, and I am including template files to my view with ng-include from an external js-file.
When I run my index.html the browser, it crashes after a long while. It seems as if the page continues to reload over and over, and my CPU monitor goes through the roof.
What on Earth can be wrong? I am fairly new at angularjs, so if anyone could point me in the right direction, I'd be very thankful.
index.html
<!DOCTYPE html>
<html lang="en" data-ng-app="angularTemplate" data-ng-controller="templateCtrl">
<head>
<meta charset="UTF-8">
<title>{{ pageName + " - " + siteName }}</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
</head>
<body>
<header data-ng-include="includeHeader()"></header>
<script type="text/javascript" src="./assets/js/templateCtrl.js"></script>
</body>
</html>
JS
var app = angular.module('angularTemplate', []);
app.controller('templateCtrl', function($scope, $http) {
$scope.includeHeader = function(){
$http.get("./assets/php/mysql.php?action=getSiteSetup")
.success(function(response){
$scope.siteName = response.siteName;
$scope.siteTagline = response.siteTagline;
});
return "./assets/templates/header.html";
}
});
the mysql.php?action=getSiteSetup is a simple sql call which returns
{"siteName":"AngularJS Template","siteTagline":"Just another template...","siteBaseURL":"http:\/\/localhost\/angularjs_template\/"}
This issue exists because of the following two implementations:
<header data-ng-include="includeHeader()">
and
$scope.includeHeader = function(){
$http.get("./assets/php/mysql.php?action=getSiteSetup")
...
}
You need to understand how AngularJS's scope works to detect change in scope. See here
Basically AngularJS will repeatedly rerun the expression given and compare it to its previous value to determine if its value has changed, if it did, then it will do whatever it needs upon scope variable change. Therefore includeHeader() here is rerun repeatedly every time AngularJS wants to check if things have changed. However inside your includeHeader, it triggers a network call every time. To make things into an infinite loop, one of the triggers for AngularJS to decide if it needs to check for scope change is upon the completion of $http. There's your infinite loop.
In short, do not use any expression for scope value check if it's process intensive and vice versa. includeHeader is NOT where you should put initialization code. Simply trigger it in controller.
For routing between pages you should use Angular-Route or ui.router.
It is described here with examples: https://docs.angularjs.org/tutorial/step_07
This uses ng-view directive witch allows you to inject content based on called url from your web-app.
Here you have ng-view docs: https://docs.angularjs.org/api/ngRoute/directive/ngView
I really recomend you to read it and solve it this way. This completly remodel your work but will let you work easier and faster in future. And also it will make much easier making a tests to it.
Also please past your header.html code for improving this answer.
Remove the Ajax request from inside the function that data-ng-include directive binds to in the controller so that the code looks like the following
var app = angular.module('angularTemplate', []);
app.controller('templateCtrl', function($scope, $http) {
$http.get("./assets/php/mysql.php?action=getSiteSetup")
.success(function(response){
$scope.siteName = response.siteName;
$scope.siteTagline = response.siteTagline;
});
$scope.includeHeader = function(){
return "./assets/templates/header.html";
}
});
Note:
You don't necessary need to bind the ng-include directive to a
function on the scope when the template is not loaded dynamically
based on user interactions

Node.js code in html file

It is possible to mix HTML with node.js commands?
I want to make my site like in PHP so:
<html>
<!-- Some HTML -->
<?php
echo "example";
?>
</html>
So, server makes all commands, which are included in HTML file and than returns pure HTML to show it in users browser. I need this, because I want to get data from MySQL database and then show it on my site.
In all tutorials I found only:
res.write("<Some html>");
And there is nothing about keeping html in separate files and add to them some server-side js.
Find a templating engine and build your application around that, because what you want is not possible.
For a list of compatible template engines, take a look here:
https://github.com/joyent/node/wiki/modules#wiki-templating
Your example using Express and EJS (which I use). Jade seems like overkill to me, but that's just my opinion.
// index.ejs (the html template)
<html>
<head></head>
<body>
<div><%= example %></div>
</body>
</html>
And in your node app:
app.get('/', function (req, res, next) {
res.render('index.ejs', {
layout: false,
locals: {
example: "Hello world!"
}
});
});
That's pretty much the basics of using EJS. I personally like it over Jade because the people I use to do up the html don't hand it to me in Jade format, and it's very similar to how I used to do php templating.
There is more you can do with the templates of course, you can put javascript in them to say, loop through an array returned by a database, include other .ejs files. You just need to dig into the docs and examples on the web.
Use the function res.write is enough.
You can generate some string with html syntax, like "<html>..</html>", then you put it into the res.write and you get response with a html file.
The point is how to generate the string with html syntax.
If we have a template file like this:
<html>
<body>
<h1>{{ "Hello" + " world!" }}</h1>
</body>
</html>
We want to get the "Hello world!" between <h1> and </h1>. So we can have the work done by:
read the template file with fs.readFile
use regular expression to get the content between {{ and }}
use eval to evaluate the content, and replace them.
After doing this, you can get the string with html syntax. and that is what most template engines(like ejs, jade) do, of course they have more complex works to do.
I hope that this can help you know more about template engine with node.js, and please forgive my poor English...
Have you tried a web application framework like express?
Check it out here!

How to dynamically load datatable?

I use RichFaces to develop some web pages, basically I'd like to display a list of my data with DataTable. But my manage bean will take a long time to obtain resource data, which blocks the web page display.
My goal is to dynamically display them, First display the web page (maybe no data yet), then once my manage bean reads one new data, it displays this as a new row in my DataTable, any idea how can I do that? or maybe a similar example is appreciate.
Load the page then fetch data using JavaScrip via an Ajax call. Ajax is very easy to implement using jQuery.
jQuery Ajax Documentation
Example: Untested!! But its something like this..
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" ></script>
<script>
// Run on page load
$(function() {
$.ajax({
url: "getMyData.html",
type: "GET"
}).success(function(data) {
// My data is in "data", if it is html then
$("#myDiv").html(data);
});
});
</script>
</head>
<body>
<h1>Hello</h1>
<div id="myDiv"></div>
</body>