SyntaxError: Unexpected token when compiling ejs - node.js

I have been stuck on this error for a while and cannot figure out why I am getting this error.
In my main server file I have set the view engine to ejs :
app.set("view engine", "ejs")
Now, when I am rendering a file from Routes
router.get("/", async function (req, res) {
res.render("main")
}
main.ejs
<h1>Hello :)</h1>
It works fine. But if I try to include partials:
<% include ./partials/header %>
<h1>Hello :)</h1>
<% include ./partials/footer %>
I get the error:
SyntaxError: Unexpected token / in C:\Users\Dacvid\Desktop\Comp Web\views\main.ejs while compiling ejs
My directory structure is shown below:

I think you're using the old syntax of ejs.
Try replacing
<% include ./partials/header %>
by
<%- include("./partials/header") %>

Related

ExpressJS, EJS: Uncaught SyntaxError: Unexpected token '<' (at file.js 1:1

I have a ExpressJS server with ejs template engine runs a Blockly app and a threejs map in a web page. My problem is that, when I go to /applications/newApp, app.ejs works well but when I go to /applications/:slug (this is a request to load a saved application) the app.ejs crashes with error below:
Uncaught SyntaxError: Unexpected token '<' (at file.js:1:1)
Uncaught SyntaxError: Unexpected token '<' (at anotherFile.js:1:1)
Here is my ejs codes:
<p hidden id="pageName">
<% if(page_name=="savedApp" ) { %>
savedApp
<% } else { %>
newApp
<% } %>
</p>
<p hidden id="slug">
<% if(page_name=="savedApp" ) { %>
<%= slug %>
<% } else { %>
none
<% } %>
</p>
these both calles same file but one works well while another crashes. These are also how server responses;
exports.getNewApp = (req, res) => {
res.render('app', {
page_name: 'newApp',
});
};
exports.loadApplication = async (req, res) => {
try {
res.render('a', {
page_name: 'savedApp',
slug: req.params.slug,
});
} catch (err) {
console.log(err);
res.status(500);
}
};
WHAT I TRIED:
I checked the opened <% %> tags, there is no error in here
I am using public files like that:
app.use(express.static(path.join(__dirname + 'public')));
app.use('/applications', express.static(path.join(__dirname + 'public/blocklyApplication')));
And I also checked following questions:
Express.js, Node.js, EJS - Uncaught SyntaxError: Unexpected token <
SyntaxError: Unexpected token ; while compiling ejs
SyntaxError: Unexpected token ,while compiling ejs
I don't get that, they are both responses same page with common url, one works well other doesnt. What should I check?
I don't know why, after trying some changes in code, adding
app.use(
'/applications/:slug',
express.static(path.join(__dirname + '/public/blocklyApplication'))
);
in my code makes everything work.
EDIT: and also in here Express-js can't GET my static files, why? there is a detailed answer about routed public.

Why does the wrong EJS tag cause this specific error: SyntaxError: Unexpected token ')'

Goal: I am trying to understand an error which occurred while trying to render a list of "secrets" (strings passed from JSON objects) in a simple Node app serving EJS files.
Code
app.js
const express = require('express');
const ejs = require('ejs');
const app = express();
app.set('view engine', 'ejs');
app.get("/secrets", (req, res) => {
const user1 = { "username": "jon", "secret": "blue blue blue"};
const user2 = { "username": "paul", "secret": "red red red"};
const users = [user1, user2];
res.render("secrets", {usersWithSecrets: users});
});
app.listen(3000, function() {
console.log("Server started on port 3000.");
});
secrets.ejs
<body>
<html>
<h1>Secrets List:</h1>
<%= usersWithSecrets.forEach((user) => { %>
<p class="secret-text"><%=user.secret%></p>
<%})%>
<hr>
</body>
</html>
Error: SyntaxError: Unexpected token ')' in C:\Users\Owner\Desktop\Sams\scode\Learning\Authentication_and_Redux\code\starting_code\Secrets-Starting_Code\views\secrets.ejs while compiling ejs
I was able to fix the error by changing the 5th line of secrets.ejs to
<% usersWithSecrets.forEach((user) => { %>
but I don't understand why I got the error that I did. I spent a very long time reviewing my code looking for a missing open parenthesis "(" before I even considered that the EJS tags were wrong. Admittedly I am a bit new to EJS, but this error was still very misleading.
Can someone please help me understand why this error was presented instead of an error stating that the EJS tags were wrong?
This happens because to EJS <%= usersWithSecrets.forEach((user) => { %> simply means to insert usersWithSecrets.forEach((user) => { in the <body> element. This is perfectly valid. EJS doesn't assume what you are wanting to do. In other words, that statement is no different than <%= hello world! %> and EJS will happily put that as the text in the <body> tag.
However, when you use the <% %> tag in <% }) %>, it tells EJS that everything here is a script and should be interpreted as javascript. Since there is only a closing bracket and parentheses and no valid javascript earlier to open these, there is now a syntax error. Changing the earlier from an output tag (<%= %>) to a script tag (<% %>) made it a valid javascript script with no error.
In short, just like the javascript interpreter can't assume your intentions, neither can the EJS parser. It couldn't possibly know that you were meaning to start a javascript script and not output usersWithSecrets.forEach((user) => { in the <body> tag. For more information on EJS see the documentation

Error: Could not find the include file "partials/head"

enter image description hereI am trying to run an ejs file and gets error Error: Could not find the include file "partials/head".
i have checked most of the articles from stackoverflow and github however not able to resolve it ...
Error: Could not find the include file "partials/head"
at getIncludePath (C:\Users\Junia\Desktop\node\node_modules\ejs\lib\ejs.js:162:13) enter
code here at includeSource
(C:\Users\Junia\Desktop\node\node_modules\ejs\lib\ejs.js:306:17)
at C:\Users\Junia\Desktop\node\node_modules\ejs\lib\ejs.js:672:26
at Array.forEach ()
at Template.generateSource (C:\Users\Junia\Desktop\node\node_modules\ejs\lib\ejs.js:648:15)
at Template.compile (C:\Users\Junia\Desktop\node\node_modules\ejs\lib\ejs.js:552:12)
at Object.compile (C:\Users\Junia\Desktop\node\node_modules\ejs\lib\ejs.js:388:16)
at handleCache (C:\Users\Junia\Desktop\node\node_modules\ejs\lib\ejs.js:212:18)
at tryHandleCache (C:\Users\Junia\Desktop\node\node_modules\ejs\lib\ejs.js:251:16)
at View.exports.renderFile [as engine] (C:\Users\Junia\Desktop\node\node_modules\ejs\lib\ejs.js:480:10)
var express=require('express');
var app=express();
var router=express.Router();
var mysql=require('mysql');
var cookieParser=require('cookie-parser');
var session=require('express-session');
app.use(session({
secret: 'secret',
resave: true,
saveUninitialized: true
//cookie : { maxAge : 60000 }
}));
var path=require('path');
var bodyParser=require('body-parser');
app.use(express.static('/'));
//Serves all the request which includes /images in the url from Images folder
app.use('/images', express.static(__dirname + '/images'));
app.use('/bs4', express.static(__dirname + '/bs4'));
app.use(cookieParser());
const ejsLint = require('ejs-lint');
var con=mysql.createConnection(
{
host:'localhost',
user:'root',
password:'',
database:'shintoj'
});
var path = require('path');
app.use('/',router);
app.use('/',express.static(__dirname + '/'));
app.set('views', path.join(__dirname, 'views/pages'));
app.set('view engine', 'ejs');// use res.render to load up an ejs view file
// index page
router.get('/', function(req, res) {
//res.send('Welcome');
res.render('index');
});
app.listen(8080);
console.log('8080 is the magic port');
console.log(app.get('views'));
index.ejs file
<head>
<%- include partials/head %>
</head>
<body class="container">
<header>
<% include partials/header.ejs %>
</header>
<div class="jumbotron">
<h2>Welcome to our services .</h2>
<p>Hello</p>
</div>
<footer>
<% include partials/footer.ejs %>
</footer>
expected actual result is ..
when i run node server.js , it should display the index.ejs file
That's because your ejs file is in another directory which is views
which mean that your partials directory is outside if your views directory..
Try this:
<%- include('../partials/head.ejs') %>
Remove include tag header and footer from ejs tag in your index.ejs file.
Or jsut include header and footer file properly. Like this
<%- include views-directory/filename %>
I got the same issue while implementing and after investing around 2-3 hr I figured out I was writing
<%- include ('partials/header') %>
instead of
<%- include('partials/header') %>
Well, the only difference was the space between include and opening bracket.
In 2021, October
I'm also having the same issue with importing files on ejs. But I used to figure it out the following way to include my other ejs partials from the parent directory.
Pros
Don't need to set up view engine and directory path on server file.
Independent directory names and locations we can achieve.
Working file: src/views/en/confirmation.ejs
Parent file: src/views/common/footer.ejs (Needs to included on each ejs file)
In src/views/en/confirmation.ejs`
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html data-editor-version="2" class="sg-campaigns" xmlns="http://www.w3.org/1999/xhtml">
<body>
<h1>this is body</h1>
</body>
<% var dir = process.cwd() %>
<%- include(dir + "/src/views/common/footer.ejs") %>
</html>
This can happen, given the way you are calling the page you need, currently the correct way to get one page within another is
<%- include('partials/navigation.html')%>

Are there Application scope variables in Node js

I wanted to know are there any application scope variables that can be accessed anywhere in the whole application.
Since I want to add data to my HTML tags using javascript, I need to transfer/get data from the server.js to the index.html
To transfer data from server.js to index.html you don't need to create global variables. You need to use a templating engine: pug, ejs or any other engine.
Just pass the data along with html file in the res.render() function and use templating syntax to display the data at the page.
Router code:
app.get('/', function (req, res) {
res.render('index', { title: 'Hey', message: 'Hello there!'});
});
Pug code:
html
head
title= title //Hey
body
h1= message //Hello there!
ejs code:
<html>
<head> <%= title %> </head>
<body>
<h1> <%= message %> </h1>
</body>
</html>

Express & EJS - layout.ejs not used

Im trying out EJS as a view engine with Express. It seems that my layout.ejs is not used. I have two views index.ejs and layout.ejs both in my 'views' folder. It seems that index.js is rendered but layout.ejs is not. The layout.ejs file should be including a CSS file but when the page is rendered in the browser this is not there. Any test test text that I place in the layout.ejs file is not output with the response.
Am I missing an additional configuration step?
Thanks!
My server.js code:
var express = require('express');
var app = express();
app.set('view engine', 'ejs');
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res){
res.render('index.ejs', {title: 'EJS Engine'});
});
app.listen(8080);
In my layout.ejs I am linking to a single css file which resides in the public folder.
layout.ejs:
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel="stylesheet" type="text/css" href="main.css">
</head>
<body>
<%- body %>
</body>
</html>
index.ejs
<div id="container">
index.html
</div>
Here's the module you need:
https://www.npmjs.org/package/express-ejs-layouts
Do the following:
npm install express-ejs-layouts // install the layout module from the command line
var express = require("express")
,path = require('path')
,fs = require('fs')
,expressLayouts=require("express-ejs-layouts") // add this requirement
, app = express();
app.use(express.bodyParser());
app.use(expressLayouts); // add this use()
app.use(express.static(__dirname));
Now the ejs engine should use your layout.
app.set('view options', { layout:'layout.ejs' });
Place layout.ejs into your views folder.
Alternately you can place layout.ejs into views/layouts folder and then use
app.set('view options', { layout:'layouts/layout.ejs' });
I have a similar issue. In my case I would rather use Jade but I have a requirement for a more "html" style template engine for a particular project. At first I considered express-partials or ejs-locals (as mentioned in a comment by Jonathan Lonowski) or even using html via the pipe or dot syntax within Jade templates (see here for more information about that option and this SO post). I am not able to introduce the additional dependencies for express-partials and ejs-locals into this project. These two projects do look good and might meet your needs.
If you do not want to use these projects, you can do something like the following:
views/layout-head.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>The title</title>
</head>
<body>
views/layout-foot.ejs
</body>
</html>
views/index.ejs (or any other page)
<% include layout-head %>
This is the index page - <%= title %>
<% include layout-foot %>
routes/index.js
exports.index = function(req, res){
res.render('index', { title: 'Express' });
}
This is not an optimal solution but it works. Most of my application will be a single page app and I have some other restrictions I have to work within so this works for my needs. This may not the best solution in many cases - especially if you have complex and/or changing layouts.

Resources