EJS template (NodeJS + express) converts decimal to integer - node.js

When I pass the data dictionary to the EJS template, it formats the decimals as integers. What's the recommended way to fix it?
const express = require('express');
const app = express();
app.set('view engine', 'ejs');
app.get('/', function(req, res) {
let data = {
lat: 42.0,
lng: 78.0
}
res.render('pages/index',data);
});
app.listen(8080);
The index.ejs template:
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
test <%= lat %>
</body>
</html>

The answer:
test <%= lat.toPrecision(8) %>

Related

Where to put Handlebars.registerHelper function in node.js project?

I want to increase "totalPrice" by 10 and then display it in handlebars templates . Here z some snippet of my handlebar file.
checkout.hbs
<ul class="shipping__method">
<li>Shipping <span>$ 10</span></li>
</ul>
<ul class="total__amount">
<li>Order Total <span>Rs. {{increasePrice totalPrice}}</span></li>
</ul>
For that i write this in my app.js file
var expressHbs = require('express-handlebars');
app.engine('.hbs', expressHbs({ defaultLayout: 'layout', extname: '.hbs'}))
app.set('view engine', '.hbs');
expressHbs.registerHelper ('increasePrice', function (price) {
price+=10;
return price;
})
And then i got error expressHbs.registerHelper is not a function. Then i came to know to write it like this
var hbs = expressHbs.create({
helpers: {
increasePrice: function(price) {
price+=20;
return price;
}
}
})
And then i got error like "missing Helper: "increasePrice" ".
👨‍🏫 You see this code below 👇, an example code using express and express-handlebars:
index.js
var express = require('express');
var app = express();
var expressHbs = require('express-handlebars');
app.engine('.hbs', expressHbs({ defaultLayout: 'layout', extname: '.hbs'}))
app.set('view engine', '.hbs');
var hbs = expressHbs.create({});
// register new function
hbs.handlebars.registerHelper('increasePrice', function(price) {
price+=10;
return price;
})
app.get('/', (req, res) => {
res.render('home', {
layout: false,
totalPrice: 300,
});
})
app.listen(3000, () => {
console.log('Server is up');
});
Now create file home.hbs in views, and put this code below 👇 in there.
home.hbs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My Example APP</title>
</head>
<body>
<ul class="shipping__method">
<li>Shipping: Total Price <span>$ {{ totalPrice }}</span></li>
</ul>
<ul class="total__amount">
<li>Order Total <span>Rs. {{increasePrice totalPrice}}</span></li>
</ul>
</body>
</html>
From the code above 👆, I hope you can understand now, where you have to put your function.
For an example: You can see on my codesandbox
I hope it's can help you 🙏.

ejs compilation error in node.js express app

I'm trying to include header.ejs and footer.ejs file with my home.ejs file.
A home.ejs file is located in views folder and the others are located in views/partials.
While including the file I get the error:
SyntaxError: Unexpected identifier in D:\wamp64\www\Training\node_pug\views\home.ejs while compiling ejs
I am a beginner in nodejs.
header.ejs
<DOCTYPE! html>
<html>
<head>
<title>
<link rel="stylesheet" hreff="app.css">
</title>
</head>
<body>
footer.ejs
</body>
</html>
service.js
var express = require('express');
var app = express();
var path = require('path');
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: true });
app.use(express.static('public'));
var session = require('express-session');
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.static(path.join(__dirname, 'public')));
const ejsLint = require('ejs-lint');
app.get('/', function(request, response) {
response.render('login');
});
app.get('/home', function(request, response) {
response.render('home');
});
app.post('/auth', urlencodedParser,function(request, response) {
var username = request.body.username;
var password = request.body.password;
if(username == 'admin')
{
//response.redirect('ejs/home');
response.render('home');
}else{
response.render('login');
}
});
var server = app.listen(8080,function(){
console.log('server is running...');
});
home.ejs
<% include partials/header %>
<h1>welcome</h1>
<% include partials/footer %>
From the docs: The recommended way to include a file is as below:
<%- include('partials/header') %>
<h1>welcome</h1>
<%- include('partials/footer') %>
The docs state that
NOTE: Include preprocessor directives (<% include user/show %>) are not supported in v3.0+.
You are probably using a v3.0+ version of EJS hence the error you are experiencing. The snippet above should solve your issue.
If you are using express 4.X you should probably use this syntax in your home.ejs.
<%- include partials/header.ejs %>
<h1>welcome</h1>
<%- include partials/footer.ejs %>

NodeJs - route parameters crash the file system on a client

This is my server
const path = require('path');
const express = require('express');
const exphbs = require('express-handlebars');
const bodyParser = require('body-parser');
const handlebars = exphbs.create({
defaultLayout: 'index',
extname: 'hbs'
});
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
require('./Server/Routes/questionnaire')(app);
app.engine('hbs', handlebars.engine);
app.set('view engine', 'hbs');
app.use(express.static(path.join(__dirname, 'Public')));
app.listen(8888, function () {
console.log('Server running on port 8888');
});
and I use this route
module.exports = function (app) {
app.get('/questionnaire', function (req, res) {
res.render('questionnaire', {
eventInfo: {
description: "TEST",
imgHost: "Resources/img_logo.png"
}
});
});
};
the code works fine. When adding a parameter to the route /questionnaire/:id no css files or client code is found.
What am I missing? Using a parameter in my route should have the correct syntax. This error just appears, when using parameters in the routes.
EDIT:
The whole directory
First I use my default HTML index.hbs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<link href="Style/base.css" rel="stylesheet">
<link href="Style/header.css" rel="stylesheet">
<link href="Style/button.css" rel="stylesheet">
<link href="Style/input.css" rel="stylesheet">
<link href="Style/link.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<script src="Client/header.js"></script>
<body>
<div id="header">
</div>
{{{body}}}
</body>
</html>
and I render my questionnaire.hbs template
<link href="Style/Templates/questionnaire.css" rel="stylesheet">
<script src="Client/Templates/questionnaire.js"></script>
<div id="content">
</div>
As mentioned in the comments, I have to write /....
When using a parameter, it seems I have to write full paths like
"/Resources/img_logo.png"
instead of
"Resources/img_logo.png"
Try this in your app.js
//comment this line
//app.use(express.static(path.join(__dirname, 'Public')));
//add this middleware
app.use(express.static('./Public'));
app.use('/Style',express.static('./Public/Style'));
app.use('/Client',express.static('./Public/Client'));

EJS does not render value returned from res.render

I'm getting the page redirects correctly however when I'm going to list this result in the front-end the value is not shown just the command of the EJS in my front-end view.
I've tried to pass the output value in several different ways but none worked...
This my root files.
My index.js
var http = require('http');
var express = require('express'),
mongoose = require('mongoose'),
ejs = require('ejs'),
nunjucks = require('nunjucks'),
path = require('path'),
mysql = require('mysql'),
bodyParser = require('body-parser'),
methodOverride = require('method-override'),
logger = require('morgan');
var errorHandler = require('errorhandler');
app.use(logger('dev'));
app.use(bodyParser());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
import config from "./config/config";
import mongodb from "./config/mongodb";
import passport from "./config/passport";
import * as setup from "./middleware/setup";
import app from "./config/express";
import routes from "./routes";
import User from './models/User';
export function start() {
return new Promise((resolve, reject) => {
mongodb().then((db) => {
let server = http.createServer(app);
// save references
app.db = db;
app.server = server;
app.config = config;
// init passport
passport(app);
// register setup check middleware
app.use(setup.check);
// setup routes
routes(app);
// start server
app.server.listen(config.server.port, (err) => {
if (err) {
return reject(err);
}
resolve(app);
});
}, reject);
});
};
app.set('views', __dirname + '/templates');
app.engine('html', require('ejs').renderFile);
var api = express.Router();
app.use('/', api);
api.get('/test-ejs', function (req, res) {
res.render('test.html', { title: 'Return sucess!' });
});
api.get("/templates",function(req, res){
var path = __dirname + '/templates/';
res.sendFile(path + "index.html");
});
My HTML template test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test EJS</title>
<meta name="description" content="">
<meta name="author" content="">
<!-- HTML5 shim, for IE6-8 support of HTML elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<!-- styles -->
<link href="stylesheets/style.css" rel="stylesheet">
</head>
<body>
<%= title %>
</body>
</html>
Thank for helping me! xD
You are using .html file for rendering the data but in your app.js you have defined it as .ejs under app.engine line.
So either you have change the .html file type to .ejs or you have to replace your app.engine line with this
app.set('view engine', 'html');

Undefined while using Cheerio on Node.js

I am trying to run Cheerio on node.js with ejs as my template. Whenever I run the server, I get 'undefined' at the the 'console.log'. Given below is my code.
Server side
app.js
/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, http = require('http')
, path = require('path')
, request = require ('request')
, cheerio = require ('cheerio');
var $ = cheerio.load('<ul id="fruits">...</ul>');
var app = express();
console.log($('[class = "orange"]').attr('id'));
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', routes.index);
app.get('/users', user.list);
var temp = $('[class="orange"]').attr('id');
app.get('/data', function(req, res){
console.log(temp);
res.send(temp); //replace with your data here
}).listen(3000);
index.ejs
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js" type="text/javascript"></script>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1><%= title %></h1>
<input type="button" id="stopButton" value="Stop Listening"/>
<p>Welcome to <%= title %></p>
<ul id="fruits">
<li id= "1" class="apple">Apple</li>
<li id = "2" class="orange">Orange</li>
<li id = "3" class="pear">Pear</li>
</ul>
<script type="text/javascript">
$(document).ready(function () {
$('#stopButton').click(function () {
$.get('http://localhost:3000/data', {}, function (data) {
$('[id="2"]').text(data);
});
});
});
</script>
</body>
</html>
In the end what I wish to do is to send a value 'temp' at the press of a button 'stopButton' to the HTML page.
If you want to render html output from cheerio, cheerio describe the following way.
var cheerio = require('cheerio'),
$ = cheerio.load('<h2 class="title">Hello world</h2>');
$('h2.title').text('Hello there!');
$('h2').addClass('welcome');
$.html(); // !!!You need this step!!!
Then on client side, use $('[id="2"]').html(data); instance of using $('[id="2"]').text(data);

Resources