I've recently switched from XAMPP/LAMP stack to MEAN stack and oh dear, these new things are amazing but I can't wrap my head around this.
In a LAMP stack, if you want to display some variable (like your username from a Database or some dynamic variable like that) you'd do something like this:
index.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<?php echo $some_var; ?>
</body>
</html>
and that's it. At the start of the file, you can pass the data from a Database to the variable and that would be it.
I don't understand how you achieve this in a MEAN stack.
Do I have to use a Template engine like EJS/Pug? If I understand it, I'd do back-end in the same file that Express is (like for example, selecting data from databases) and then I'd do something like this:
app.js
app.set("views", "./views");
app.set("view engine", "pug");
app.get("/", (req, res) => {
res.render("index", {message:"Hi"});
});
Is that how you send data from server→client in a production/deploy environment? Is there a more practical solution to it? Given that pug code is way too different from HTML (for example). Thanks and sorry for my english.
In a MEAN stack, you would use Express as the backend API and pass JSON data to the frontend, which could be Angular, React, Vue, etc.
For templating with Express, this should get you started. Let us know if this helps :)
Related
In my express app, I am keeping the below config:
var express = require("express");
var path = require("path");
var jsonServer = require("json-server");
var app = express( );
app.use(express.static('public'));
app.get("/", function( req, res ) {
res.sendFile( express.static( path.join(__dirname, "/public/index.html" ) ) );
});
app.use('/api', jsonServer.router('./db.json'));
app.listen( 3000 );
All this is works fine. the problem is, I am not able to add the jquery from node_modules. here is my HTML :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Promise Defined</title>
<script src="node_modules/jquery/dist/jquery.js" type="text/javascript"></script> //not working sibling folder of public
<link rel="stylesheet" href="styles/app.css"> //works fine. inside public folder
</head>
<body>
<h1>New Title</h1>
</body>
</html>
What is the correct way to fix this? or how to handle this kind of scenario?
Thanks in advance.
node.js does not serve any files by default (unlike some other web servers). So, if you want node_modules/jquery/dist/jquery.js to work, then you have to either make sure that your express.static() line of code will include that file or you have to define a route specifically for that file. Also, it is sometimes dangerous to use a relative path with no leading / because that makes it relative to the path of your page which is generally not necessary and can make things difficult if you want to serve the same file in lots of different pages on your site.
For example, you could do this in the web page:
<script src="/jquery.js" type="text/javascript"></script>
And, this:
app.get("/jquery.js", function(req, res) {
res.sendFile(path.join(__dirname, "node_modules/jquery/dist/jquery.js"));
});
Personally, I would probably move jquery.js to a public/scripts directory on my server so I'm not serving anything out of the node_modules directory, so all my publicly served files are centralized in one place so it's entirely clear what can be served to a client and what cannot and so I could design one or two express.static() statements to serve all my public files.
I am familiar with Angularjs(1.x) and use templates in directives.
Currently I am learning nodejs and as a part of the course template engines are mentioned. What are the advantages of using them on the backend?
Currently I can't see any use.
If you have data (say from a database) that needs to be rendered to HTML, you can use a template engine to take the data and a template and render it to HTML (which subsequently gets served to the client).
If your frontend app does the same, using XHR calls or something similar to retrieve the data from the server, it's generally not useful to render to HTML server side (instead, the data gets sent as JSON to the client).
So it depends on how your app (both frontend and backend) is structured if it makes sense or not to use a templating engine.
There's also hybrid solutions where the initial HTML is rendered server side, and then the client side "takes over". This is something that, for instance, React supports. The big idea there is that you can use the same components both on the server and on the client, and that when a page is opened, the user will get to see a fully rendered initial page (instead of the client side having to retrieve the data from the backend first and then rendering the page).
You actually dont need them, but they have a lot of features that makes your pages more dynamic..
For example you can render just HTML using this code
app.get('/',function(req,res){
res.sendFile(path.join(__dirname+'/index.html'));
//__dirname : It will resolve to your project folder.
});
But with engines you can send data to template.
http://expressjs.com/en/api.html#res.render
// pass a variable to the view
res.render('somePage', {
title: 'Awesome title',
userFriends: friendsList,
name: 'loggedUserName'
});
And now on front-end templates(EJS in this case) will populate html with data that you send in. So html became dynamic and you can make each page looks different for each user.
<ul>
<% for(var i=0; i<userFriends.length; i++) {%>
<li><%= userFriends[i] %></li>
<% } %>
</ul>
With just HTML you will need to make a lot of unnecessary AJAX calls to get and add data into html which is bad idea.
Hope this helps.
A view engine allows you to render HTML with options. For example, using squirrelly, I can create a file that looks like this:
<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
</head>
<body>
{(userIsSignedIn){<!-- if the user is signed in, display username and description-->
<p>{{username}} is {{description}}</p>
}}
{(!userIsSignedIn){<!--if user isn't signed in, ask them to sign in-->
<p>Sign in to view this page</p>
}}
</body>
</html>
So I could listen, for example, to a dynamic user profile URL with Express and then return dynamic content.
It's almost 2020, Template literals are literally meant to replace template engines.
https://medium.com/#PaulBrowne83/do-we-really-need-template-engines-anymore-214eb6bc112e
I want to build a website as a Single Page Application.
For what I understand a SPA sends a single entry point to the application in the form of an HTML file.
So I would like to use Node and Express to serve the main page and to then serve HTML for the content between the header and footer that gets updated using AJAX calls when a user navigates the site.
I know how to create a restful API to serve data as JSON but not much on how to deal with the HTML parts of the SPA that are changing.
The question: how could this serving of HTML parts be implemented on the server using Node and Express (and eventually a template engine like handlebars, if it helps)?
And does it actually make sense? (A header and a footer are not much data to reload after all.)
You can definitely do this with node.js. First you set up an HTML template engine, for instance Swig, (but you can use others) and you configure the standard options to render html pages:
var swig = require('swig');
app.set('view engine', 'html');
app.set('view options', {
layout: false
});
app.engine('html', swig.renderFile);
app.set('view cache', false);
// To disable Swig's cache, do the following:
swig.setDefaults({ cache: false });
app.use(express.static(__dirname + '/public'));
Second you set up an endpoint which serves your main HTML page.
app.get('/',function(req, res) {
res.render('index');
};
Then you can create node.js endpoints which will get your data:
app.get('/users', function(req, res) {
// Do database stuff here
res.status(200).send(results);
}
Then you set up your HTML file:
<!DOCTYPE html>
<html ng-app="app">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="stylesheets/bootstrap.min.css" rel="stylesheet">
<title>fast MEAN</title>
</head>
<body ng-controller="MainController">
<div class="col-md-12" style="background-color: #006699">
</div>
{% raw %}
{{helloWorld}}
<ng-view></ng-view>
<script src="js/angular.min.js"></script>
<script src="js/angular-route.min.js"></script>
<script src="app.js"></script>
{% endraw %}
</body>
</html>
Where everything outside of {% raw %} and {% endraw %} will be rendered with data using the node/swig template data, and everything inside those tags can be rendered with whatever framework you are using inside (jquery, angular, react) etc.
An example of this simple single page application is on my github, there's one version for angular and one for react. Hope that helps.
https://github.com/coguy450/fastMEAN
Is there any way using express + swig template for nodeJS to pass variables from the server side to client side javascript? I know it can be done in Jade but I'd rather stick with a template engine that more closely resembles HTML. Thanks for the help guys!
OK I will assume that you could configure your express with consolidate.swig if not please read this link (http://tinyurl.com/kcs8kvy).
Well I didn't find the direct way to pass variable values to client javascript but I have found a workaround.
for instance you're sending an object, in your route at express:
app.get("/", function(req, res){
var myUser = { name: "Obama" };
res.render("index", {user: myUser});
});
then in your index.html file you can create a script tag:
<html>
<body>
<script>
var username = "{{user.name}}";
</script>
<script src="whatever.js"></script>
</body>
</html>
and then in your whatever.js file the username variable will be available with its correct value. I hope that this help you.
To pass json objects from backend server to the template you can do:
var data = {{jsonData|raw|json}}
I am trying to serve an html page with a linked js script using node.js and express.
This is the server that provide the page:
var express = require("express");
var app2 = express();
app2.get('/', function(req, res) {
res.sendfile('./index.html');
});
app2.listen(process.env.VCAP_APP_PORT || 3000);
and this is the page:
<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
</head>
<body>
<h1>Demo</h1>
<script src="/js/socket.io.js"></script>
<script src="/js/codice.js"></script>
</body>
As you can see I have two js scripts in my js folder but they are not loaded when I launch the page. What can I do?
What you would normally do is place any public resources (JavaScript files, CSS files, images etc) in a directory (Express names it public by default) and then use the express.static middleware in your app.configure call:
app.configure(function () {
// Various other middleware functions...
app.use(express.static(path.join(__dirname, "public")));
});
This effectively runs a static file server which will return any file inside the public directory. Currently, your browser is making a request for your JS files, but the Express server doesn't know what to do with them. They will eventually time out.
If you generate the initial state of your app with the global express executable (available if you installed Express via npm globally), it will set most of this up for you.