CAN we do something like <% alert("TEMP") %> in EJS - node.js

I have sent a variable in node.js from res.render() function and I have to use that variable for my script in EJS templating for DOM manipulation.

From Node.js:
res.render('index', {TEMP: 'xyz'});
In the HTML:
<p>This is a HTML demo</p>
<div>
I'm the TEMP variable: <%= TEMP %> <!-- this is going to output xyz -->
<script>
var getTemp = <%= TEMP %>;
console.log(getTemp);
</script>
</div>

Related

Express nodejs Handlebars not rendering database content correctly inside EJS file

Im having a problem with my express nodejs project where the handlebars wont render on my ejs file. I created some handlebars which fetch some data from a database. When I render the hbs files the content from the database is displayed correctly, but when I include the hbs files in my ejs file together with my page header and footer the content from the database is not retrieved. I would appreciate any help.
cars.hbs
<!DOCTYPE html>
<html>
<body>
<p> The {{dbcars.model}} features a {{dbcars.specs.engine}} engine... </p>
</body>
</html>
home.ejs
<body>
<p> <%- include('navbar.ejs') %> </p>
<p> <%- include('handlebars/cars.hbs') %> </p>
<p> <%- include('footer.ejs') %> </p>
</body>
</html>
(note: when I render (handlebars/cars.hbs) instead of (home.ejs) the handlebars render correctly. )
car.js
router.get('/vehicle/:id', async (req, res) => {
Car.findById(req.params.id, function(err, carRouter) {
res.render("home.ejs", {
dbcar: carRouter
})
This is the result im getting:
(navbar)
The {{dbcars.model}} features a {{dbcars.specs.engine}} engine...
(footer)
This is the result im trying to get:
(navbar)
The Nissan Sentra features a 2.0 L 4-cylinder engine...
(footer)
You should create cars.ejs as well
cars.ejs
<% if (dbcar.length > 0) { %>
<% dbcar.forEach(dbcars => { %>
<p> The <%= dbcars.model %> features a <%= dbcars.specs.engine %> engine... </p>
<% }) %>
<% } else { %>
<p>There is no information to display.</p>
<% } %>
home.ejs
<%- include('handlebars/cars.ejs'); %>
car.js
router.get('/vehicle/:id', async (req, res) => {
Car.findById(req.params.id, function(err, carRouter) {
res.render("cars.ejs", {
dbcar: carRouter
})
};
};

I am facing the some error in my ejs file can someone please assist me?

The error I am facing is as follows:
I have the following code written in server.js file. What am I doing wrong?
var express = require('express');
var app = express();
var instagram = require('instagram-node').instagram();
const ejsLint = require('ejs-lint');
app.use(express.static(__dirname + '/public'));
app.set('view engine', 'ejs');
instagram.use({
client_id:'1063599834134140',
client_secret:'66cbe60a931310beb7a8cf6d4ec7a12f '
});
app.get('/', function(req, res){
//
instagram.media_popular(function(err, medias, remaining, limit)
{
res.render('pages/index', {grams: medias});
});
});
app.listen(8080, function(err)
{
if(err)
{
console.log("Error Occured");
}
else
{
console.log("listening on port 8080");
}
});
And the following is index.ejs
<!DOCTYPE html>
<html>
<head>
<% include ../partials/head %>
<title></title>
</head>
<body class="container">
<header>
<% include ../partials/header %>
</header>
<main>
<div class="row">
<% grams.forEach(function(true){ %>
<div class="instagram-pic col-sm-3">
<a href="<%= gram.link %>" target="_blank">
<img src="<%= gram.images.standard_resolution.url %>" class="img-responsive">
</a>
</div>
<div class="instagram-bar">
<div class="likes">
<span class="glyphicon glyphicon-heart"></span>
<%= gram.likes.count %>
</div>
</div>
<div class="comments">
<span class="glyphicon glyphicon-comment"></span>
<%= gram.comments.count %>
</div>
<% }) %>
</div>
</main>
<footer>
<% include ../partials/footer %>
</footer>
</body>
</html>
Looks to me like your includes are wrong. Using the ejs-lint package that your error message references gives the following:
Unexpected token (4:17) in asdf.ejs
<% include ../partials/head %>
In looking at some ejs docs, the syntax they give for include is:
Includes are relative to the template with the include call. (This requires the 'filename' option.) For example if you have "./views/users.ejs" and "./views/user/show.ejs" you would use <%- include('user/show'); %>.
You'll likely want to use the raw output tag (<%-) with your include to avoid double-escaping the HTML output.
So in your case that would be
<%- include('../partials/head') %>
And of course, same for your other includes.
Also for future reference, it would be way better to copy/paste the error text into a code block in your question, instead of linking a screen shot.

EJS include as wrapper

Can I include another .ejs file that will wrap the current content?
I want to have a general layout like this:
layout.js:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="header"></div>
<div id="content">
<!-- I want to "inject" my code here -->
</div>
</body>
</html>
and I want to use this template from another file, like this:
content.ejs
<% inside(layout) ? { %>
content
<% } %>
Can I do something like this?
I'm currently doing this the other way around, I call layout with a parameter include_name but it's a little inconvenient. I would like to call the relevant content.ejs which includes the generic content itself. Is this possible?
Thanks,
From EJS Documentation:
EJS does not specifically support blocks, but layouts can be
implemented by including headers and footers, like so:
<%- include('header') -%>
<h1>
Title
</h1>
<p>
My page
</p>
<%- include('footer') -%>
Although some frameworks have some facilities to deal with problem. for example Express until version 3.x had layout support and for latest versions you could use it as a stand alone npm package: express-partials
With this package in place you define a <%- body %> region in your skeleton template (layout.ejs) and when you call your desired layout (content.ejs), express will render layout.ejs with content.ejs as <%- body %> ( unless you set {layout:false} which then it only renders content.ejs):
layout.ejs
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="header"></div>
<div id="content">
<%- body %>
</div>
</body>
</html>
content.ejs
content
app.js
var express = require('express')
, partials = require('express-partials')
, app = express();
// load the express-partials middleware
app.use(partials());
app.get('/',function(req,res,next){
res.render('content.ejs')
// -> render layout.ejs with content.ejs as `body`.
})
app.listen(3000);

Storing Express data in global variable through view

I have a data object "bootstrappedUser" being passed into the view through a route.
app.get('/', function(req, res) {
res.render('index.ejs',{
bootstrappedUser: req.user,
page: 'rest'
});
});
I'd like to store the "bootstrappedUser" JSON object into a global variable and use that variable to keep persistent login. Currently the window.bootstrappedUserObject is being accessed when bootstrappedUser is defined but it is not being set to anything.
<% if (bootstrappedUser!= undefined) { %>
<script>
window.bootstrappedUserObject = <% bootstrappedUser %>
</script>
<% } %>
I am receiving the following source code on login
<script>
window.bootstrappedUserObject =
</script>
You want to use <%= %> instead of <% %>:
<% if (bootstrappedUser!= undefined) { %>
<script>
window.bootstrappedUserObject = <%= bootstrappedUser %>
</script>
<% } %>
<% %> just evaluates JavaScript whereas <%= %> interpolates the result of an expression into your template.

knockoutjs in express using ejs

I would like to start using knockoutjs in a web app currently based on Nodejs with express using ejs view engine.
index.ejs
<% layout('layout') -%>
<!-- Jquery Include-->
<script src="/js/jquery-2.1.0.min.js"></script>
<!-- Knockout Javascript Dependency-->
<script src="/js/knockout-3.0.0.js"></script>
<script type="text/javascript">
var viewModel = {
firstName : "Bert"
};
ko.applyBindings(viewModel);
</script>
<p>First Name: <span data-bind="text: firstName"></span></p>
It appears that knockout js is loading properly however, the data-binding is not working I simply see.
First Name:
Is there a compatibility issue loading knockout in an ejs file?
There are no compatibility issues with ejs - as far as I know - however you need to call ko.applyBindings after your DOM is loaded, from the documentation:
To activate Knockout, add the following line to a block:
ko.applyBindings(myViewModel);
You can either put the script block at the bottom of your HTML
document, or you can put it at the top and wrap the contents in a
DOM-ready handler such as jQuery’s $ function.
So you need to change your template to move the ko.applyBindings at the end:
<% layout('layout') -%>
<!-- Jquery Include-->
<script src="/js/jquery-2.1.0.min.js"></script>
<!-- Knockout Javascript Dependency-->
<script src="/js/knockout-3.0.0.js"></script>
<p>First Name: <span data-bind="text: firstName"></span></p>
<script type="text/javascript">
var viewModel = {
firstName = "Bert"
};
ko.applyBindings(viewModel);
</script>
Or use the jQuery’s $ function:
<% layout('layout') -%>
<!-- Jquery Include-->
<script src="/js/jquery-2.1.0.min.js"></script>
<!-- Knockout Javascript Dependency-->
<script src="/js/knockout-3.0.0.js"></script>
<script type="text/javascript">
var viewModel = {
firstName = "Bert"
};
$(function() {
ko.applyBindings(viewModel);
});
</script>
<p>First Name: <span data-bind="text: firstName"></span></p>

Resources