Express layouts error - variable not defined - node.js

I am using express-ejs-layouts and am seeing the following error in the console log:
>> 5| <title><%= title %></title>
title is not defined
I do indeed have the following element defined in my layout.ejs file:
<title><%= title %></title>
I am populating this variable from one of my route files:
router.get('/', function(req, res) {
res.render('index', {
title : 'Express'
});
});
Any idea what I am missing? Thanks!

I figured this out. There was another variable (description) that was not defined. As soon as I set the 'description' variable this worked. Seems a bit odd that the error message would be for 'title' though.

Related

Pug not rendering variables defined in res.render

Does anybody know why my tour variable is not rendered on the site. My paragraph is rendered but tour is undefined
app.get('/', (req, res) => {
res.status(200).render('base', {
tour: 'The Forest Hiker',
user: 'Eldin',
});
});
(base.pug file)
doctype html
html
head
title Natours
link(rel='stylesheet' href='css/style.css')
link(rel='shortcut icon' type='image/png' href='img/logo.png')
body
h1= tour
p This is just some text
I found the answer. It should be used #{tour}

Pug: Cannot read property 'title' of undefined

I want to pass an array to a pug view and construct the view by iterating over it, but I get an error when I load the view.
PUG view
include includes/header.pug
body.index
include includes/nav-bis.pug
.hero
.hero-body
.container
.box
for post in posts
h1= posts[post].title
p= posts[post].content.substring(0, 100)+" ..."
a(href="/posts/" + posts[post].title) Read More
app.js
app.get('/blog', function(req, res) {
console.log(posts);
res.render('blog', {posts: posts});
});
You are calling the post in wrong way. Try the below code:
h1= post.title

MEAN js dynamic title

how to add dynamic title for each pages of the MEAN js application. in the layout.server.js has defined the title as follows.
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{{title}}</title>
so how can we make dynamic title?
Some people might be mislead thinking that besides it is already dynamic, it can be changed and it is controlled by angular out of the box because of having an expression with {{ }} but that's not quite true.
In fact {{title}} could mean an expression that should be evaluated against scope.title, however if you take a deeper look at MEAN.js you will see that it is using the swig template engine which also uses {{ }} to define variables. In this case, {{title}} is NOT an angular expression, it is a swig variable which was passed via express/swig and it can be changed in the config/env/default.js (in MEAN.js 0.4.0).
If you want the title to be changed in the frontend (i.e. possible to change it within angular logic) you have to assign a scope variable to the title element or use a custom directive. Even if, at first, the title value is the one defined using express/swig, angular can take control afterwards and change it accordingly to your needs.
One solution could be to define the title in your angular states like this:
.state('some-state', {
url: '/someurl',
templateUrl: 'some-path-to-view',
data: {
title: 'My new title',
}
})
And then listen for the $stateChangeSuccess event to set the title:
$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
console.log(toState.data.title); // Prints the new title to the console
// Set the title
});
EDIT: First paragraph rewritten for more coherence.
To add to the accepted question, in the MeanJS stack you can do the following:
Create a new view in the modules/core/client/views ex. title.client.view.html.
In the file title.client.view.html you can get the title by doing:
<div ng-controller="HeaderController">
<span>{{$state.current.data.pageTitle}}</span>
</div>
The HeaderController has a $state variable that contains the current state title specified in:
.state('some-state', {
url: '/someurl',
templateUrl: 'some-path-to-view',
data: {
title: 'My new title',
}})
Then to get the title in the modules/core/server/views/layout.server.view.html file you include title.client.view.html like this:
<div ng-include="'/modules/core/client/views/title.client.view.html'"></div>
This will render the title of a state dynamically as you navigate.
The MEAN.JS page title is already dynamic and can be found at modules/core/client/directives/page-title.client.directive.js:
function listener(event, toState) {
var applicationCoreTitle = 'MEAN.js',
separator = ' - ',
stateTitle = applicationCoreTitle + separator;
Whereas 'MEAN.js' is the default page title and can be changed accordingly.

Why is my jade index page blank?

I'm broadly following this tutorial on Express, Mongo and Jade, and although I've successfully fetched back some data from mongo, but jade isn't rendering my page.
http://blog.ijasoneverett.com/2013/03/a-sample-app-with-node-js-express-and-mongodb-part-1/
Snippets are:
app.js:
app.get('/', function(req, res) {
employeeProvider.findAll(function(error, emps) {
// adding logging here shows that 'title' and 'emps' are correctly populated
res.render('index', { title:'Employees', employees:emps });
});
});
layout.jade:
doctype html
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body
block content
index.jade:
extends layout
block content
h1= title
div
each employee in employees
div.employee
div.created_at= employee.created_at
div.title= employee.title
div.name= employee.name
When I extract the source from the page displayed in the browser, it just shows this:
<!DOCTYPE html><html><head><title>Employees</title><link rel="stylesheet" href="/stylesheets/style.css"></head><body></body></html>
In fact, nothing I put in jade.index to simplify it seems to get rendered. eg this also renders a blank page:
index.jade:
extends layout
block content
h1= title
Check again the tutorial and follow it (realy), since your code is diferent...
http://blog.ijasoneverett.com/2013/03/a-sample-app-with-node-js-express-and-mongodb-part-1/
The index.jade should be:
extends layout
block content
h1= title
#employees
- each employee in employees
div.employee
div.created_at= employee.created_at
div.title= employee.title
div.name= employee.name
a(href="/employee/new")!= "Add New Employee"
There are some needed css over #employees and
the each loop needs a - before itself.

Send multiple variables through render with Express

Maybe a stupid question but, is it possible to send multiple variables through res.render() in Express ?
Because, when I do
res.render('index', { title: 'Express', name: 'Arnaud' });
I've all this pretty error telling me name is not defined.
In this view
extends layout
block content
h1 Salut #{name}
p Welcome to #{title}
Any idea ?
In route:
res.render("index", { data: { title: "Express", name: "Arnaud" } })
In view:
<%= data.title %>
<%= data.name %>
I also got this problem for a long time and found a workaround: to pass a variable you just should do
res.locals.title = "Express";
res.locals.name = "Arnaud"
res.render("index");
The both variables Express and Arnaud will be given to the EJS context
Weird thing is weird : I regenerated a new Express project and everything is fine...

Resources