rendering in nodejs using express to html - node.js

I'm trying to get values from nodejs into HTML. I've seen lot of answers, but none of them is working.
here what I've done so far:
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Page Title</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='stylesheet' type='text/css' media='screen' href='main.css'>
</head>
<body>
<div>
<a id="test" name="test"> <%=name%></a>
</div>
</body>
</html>
app.js
const express =require('express')
const app = express();
var os = require( 'os' );
var path = require('path')
const PORT = process.env.PORT ||2000;
app.engine('html', require('ejs').renderFile);
app.get('/',(req,res)=>{
res.sendFile(path.join(__dirname+'/index.html'))
})
app.get('/test', (req, res)=> {
var name = 454;
res.render( "/index.html", {name:name});
});
app.listen(2001)
I don't get what I'm doing wrong. but it doesn't work as expected.
any idea how may I solve this ?
thanks in advance !

First, create a folder views and put your index.ejs right there (though, I am not sure, the extension have to be .ejs).
Then set the engine with:
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
And change your routing to:
app.get('/', (req,res) => {
res.render('index', { name: 'Test' });
});
Edit: I have used the express application generator and also checked Using template engines with Express.
Edit: According to the extension .ejs:
One thing to note is that all files in which ejs syntax are used in
must be saved with a .ejs extension [...]
Taken from Using EJS as a Template Engine in your Express App, not from the official docs.

Related

Can Not Get file EJS Under Views Directory

In this problem, I tried to render ejs after update the data from UI. Here is my code,
const express = require("express");
const bodyParse = require("body-parser");
const date = require(__dirname + "/date.js");
const app = express();
const port = 3000;
app.set("view engine", "ejs");
app.use(bodyParse.urlencoded({ extends: true }));
var path = require('path');
let items = ["Buy Food", "Cook Food", "Eat Food"];
let itemWorks = [];
app.get("/", function (req, res) {
let day = date.getDay();
res.render(path.join(__dirname + "/views/list.ejs"), { listTitle: day, listItem: items });
items.pop;
app.post("/", function (req, res) {
let item = req.body.foodservice;
if(res.body.list === "work"){
itemWorks.push(item);
res.redirect("/work");
}else{
items.push(item);
res.redirect("/");
}
items.push(item);
res.redirect("/");
});
});
Here is my list.ejs:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>To Do List</title>
</head>
<body>
<h1><%=listTitle%></h1>
<ul>
<% for(var i = 0; i < listItem.length; i++){ %>
<li><%=listItem[i]%></li>
<% } %>
</ul>
<form action="/" method="post">
<input type="text" name="foodservice" placeholder="New Item" autocomplete="off"/><br /><br />
<button type="submit" name="button" value=<%=listTitle%>>+</button>
</form>
</body>
</html>
Here is my project's structure:
BRANDNEW_PROJECT views /list.ejs app.js data.js
However, when I have executed it=> errors have been displayed as bellow
TypeError: Cannot read properties of undefined (reading 'list')
at E:\WEB DEVELOPMENT\NodeJS\BrandNew_Project\app.js:25:15
I have tried to debug by putting log to check whether it already points to file that I want or not and the path is correct and also to tried set up file path like this:
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
However, the issues have not been resolved.
What can be the reason here? Thanks a lot for your help.
Live working URL : https://stackblitz.com/edit/node-dmtquz?file=index.js
Views folder is default in EJS.
Concept:
when render html pages you must take care path will start for other inside views as root
when render html pages you must take care path will start for other inside views as root.
Not render views/layouts/index use layout/index because,EJS make views (or your directory) as active directory for it.
if you want to change the directory use app.set("views", path.join(path.resolve(), < dir name >)).
Structure:
views
-------- layouts
---------------- index.ejs (this file i rendered as root)
-------- partials
-----------------footer.ejs, header.ejs etc
Hope this will clear up your problem
var express = require("express");
var app = express();
// set the view engine to ejs
// app.set("views", __dirname + "/views");
app.set("view engine", "ejs");
// use res.render to load up an ejs view file
// index page
app.get("/", function (req, res) {
res.render("layouts/index" , {
displayTitle: "items viewer",
item: ["item1", "item2"]
});
});
// about page
app.get("/about", function (req, res) {
res.render("layouts/about");
});
app.listen(8080);
console.log("Server is listening on port 8080");
<!-- root dir, views/layout/list.ejs -->
<!DOCTYPE html>
<html lang="en">
<body>
<%= displayTitle%>
<hr />
<% for (let i of items) { %>
<br />
<%= i %> <% } %>
</body>
</html>
I think you need to use path.resolve instead of path.join like this:
res.render(path.resolve(__dirname + "/views/list.ejs"), { listTitle: day, listItem: items });
You might also need to update your import of the date object at the top to use path.resolve like this:
const date = require(path.resolve(__dirname + "/date.js"));
In my code I use path.resolve anytime I use __dirname

Pug does not replace parameters with values

The docs of Pug say all the parameters will be replaced with values if they have this form: #{parameter_name} This doesn't work for me.
My code:
//Template
doctype html
html(lang="en")
head
title= title
body
h1
Task is #{task_id}
p
task is #{task_id}
company is #{company_id}
//javascript
var express = require('express')
var app = express()
const util = require('util');
app.set('view engine', 'pug')
app.get('/', function (req, res) {
res.send('Hello World!')
})
app.locals.pretty = true
app.get('/task/:company_id/:task_id',function(req,res) {
res.render('task',{task_id: req.query.task_id,company_id: req.query.company_id});
});
app.listen(8080, function () {
console.log('Example app listening on port !')
})
And the output:
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
</head>
<body>
<h1>
<Task>is </Task>
</h1>
<p>
<task>is </task>
<company>is </company>
</p>
</body>
</html>
No variable was interpreted!!! What is wrong here? I am following the docs!!! (I am using latest version, installed yesterday)
Looks like you are refering to the query string instead of parameters in your nodejs
Please change your code to this
res.render('task',{task_id: req.params.task_id,company_id: req.params.company_id});
You need to use params not query

how do I render a handlebars page from a routing module

I am learning nodejs with express platform. I generated an express project and there are 2 routing files that I edited. One routing file is "users.js" and it's supposed to render layou.hbs when '/users' is requested, the other is "index.js" and it's supposed to render "home.hbs" when '/' is requested. the problem is, when '/' is requested on the url box, i get layout.hbs output on the browser. What am i doing wrong?
Here is the code from the files.
index.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('home', {title:Express});
});
module.exports = router;
user.js
var express = require('express');
var router = express.Router();
router.get('/users', function(req, res, next) {
res.render('layout', {title:Express});
//res.send('respond with a resource');
});
module.exports = router;
Home.hbs
</!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<p>goodbye World</p>
</body>
</html>
layout.hbs
</!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<p> Hello World!</p>
</body>
</html>
if i visit localhost:3000, I expect to see "goodbye world" but I see "hello world", what is wrong with this code? Thank you.
In both the files you are rendering 'home'. In line res.render('home', {title:Express});
In user.js do this:
res.render('layout', {title:Express});
Cheers:)
You should remember to require express-hbs and tell express to use that. Your main app.js or any other names you gave that file should look like this.
var http = require('http');
var express = require('express');
var hbs = require('express-hbs'); //load handlebars
var app = express();
// setup hbs view engine
app.set('view engine', 'hbs');
//location of your views folder
app.set('views', __dirname + '/views');
http.createServer(app).listen(3000);
Whatever template you render, it will be loaded as the body of your layout. For this to work, your layout should look like:
</!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
{{{body}}}
</body>
</html>
The actual body contents should go in the template you render
home.hbs
<p> Hello World!</p>
goodbye.hbs
<p> Goodbye World!</p>
So doing
res.render('home');
Would show "hello world" whereas rendering
res.render('goodbye');
Would display "Goodbye world"
If you wanted to use a different layout to wrap a given template, you can override the default:
res.render('other', {layout: 'other_layout'});
BTW, passing the variable "title" as
{title: Express}
Means nothing. The "Express" variable isn't declared. You should instead use a defined variable or pass a string literal
{title: 'Express'}
And, to have it displayed in the generated HTML, the layout would use it like this:
</!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
</head>
<body>
{{{body}}}
</body>
</html>
Please note the body part has 3 curly braces whereas the template vars use only 2.

How do I render a page in Node.JS with hogan-express

How do I render a page in node (using a router) which just passes a value to the template engine for me to use?
So for instance (this is the real code):
var apiRouter = express.Router();
apiRouter.get('/myPosts', function(req, res){
userPostsModel.findOne({'profileID':req.session.facebookProfileId}, function(err, userPosts) {
if(userPosts) {
res.json({
posts : userPosts.posts
});
} else {
console.log('You do not have any posts');
}
})
})
And the template engine part (html file):
<!doctype html>
<head>
<meta charset="UTF-8">
<title>My Posts</title>
</head>
<body>
<p>Post 1</p>
<p>Post 2</p>
</body>
</html>
I am expecting this to render the page but instead, I am getting this (on the webpage):
{"posts":["12345667"]}
For my template engine, I am using 'hogan-express', as below:
app.engine('html', require('hogan-express'));
app.set('view engine', 'html');
I know the res.json may be wrong here but I am not getting anywhere with this. The documentation for node and the routers is all over the place!
As #Molda has answered in the comments, below, it should be like this:
res.render('template-name', { posts:userPosts.posts});
Tried it and worked for me.

nodejs send html file to client

I use this function to send html file to client, but in client I get nothing (blank page) without error. Something I wrong?, please help?
var express = require('express');
var fs = require('fs');
var app = express();
app.set('view engine', 'jade');
app.engine('jade', require('jade').__express);
app.get('/test', function(req, res) {
fs.readFile(__dirname + '/views/test.html', 'utf8', function(err, text){
res.send(text);
});
var port = process.env.PORT || 80;
var server = app.listen(port);
console.log('Express app started on port ' + port);
My test.html file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style something here </style>
<title>Test</title>
<script src="..."></script>
</head>
<body>
<div> Somthing here </div>
<script type="text/javascript">
//something here
</script>
</body></html>
Try your code like this:
var app = express();
app.get('/test', function(req, res) {
res.sendFile('views/test.html', {root: __dirname })
});
Use res.sendFile instead of reading the file manually so express can handle setting the content-type properly for you.
You don't need the app.engine line, as that is handled internally by express.
you can render the page in express more easily
var app = require('express')();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.get('/signup',function(req,res){
res.sendFile(path.join(__dirname,'/signup.html'));
});
so if u request like http://127.0.0.1:8080/signup that it will render signup.html page under views folder.
After years, I want to add another approach by using a view engine in Express.js
var fs = require('fs');
app.get('/test', function(req, res, next) {
var html = fs.readFileSync('./html/test.html', 'utf8')
res.render('test', { html: html })
// or res.send(html)
})
Then, do that in your views/test if you choose res.render method at the above code (I'm writing in EJS format):
<%- locals.html %>
That's all.
In this way, you don't need to break your View Engine arrangements.
The "../" is considered malicious and will result in ForbiddenError: Forbidden at SendStream.error... exception.
The way to go is using a path module:
var path = require('path');
res.sendFile(path.resolve('views/auth/success.html'));
var app = express();
app.get('/test', function(req, res) {
res.sendFile(__dirname + "/view/test.html")
});
Here __dirname, gives you the current path where your files are saved. So in res.sendFile(), we first tell our current location by __dirname + (then we locate the specific file which should we shown on the home page i. e ) "vies/test.html".
Follow this simple process and send html file ->
res.sendfile("views/home.html"); // don't use capitla latter F with sendFile you must be use small letter f
example : sendfile();

Resources