Ejs rendered vars are undefined - node.js

I'm writing my first webb ap with nodejs and express, using ejs templates.
now when I'm rendering the html files it all works fine, but when I try to render the files with parameters, it seems like the rendered ejs template can't find the parameters I've sent to it.
here is my file structure :
project/
Views/
index.ejs
login.ejs
public/
all the css files ..
node_modules/
server.js
and here is my server.js :
var express = require('express');
var app = express();
const cookieParser = require('cookie-parser');
const session = require('express-session');
const bodyParser = require('body-parser')
app.set('view engine', 'ejs');
app.use(express.static(__dirname + '/Public'));
app.use(cookieParser());
app.use(session({secret: '1234567890QWERTY',resave: false, saveUninitialized: false})); // change the secret to safer one
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.get('/', function(req, res) {
if (req.session.user == undefined) {
// if user is not logged-in redirect back to login page //
res.render('login');
} else {
console.log(req.session.user);
res.render('index', {username:req.session.user});
}
});
app.get('/login', function(req, res) {
res.render('login');
});
app.listen(8080);
console.log('port: 8080');
and here is my index.ejs file:
<!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, shrink-to-fit=no">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="../../favicon.ico">
<title>Dashboard</title>
</head>
<body>
<div><%= username %></div>
</body>
</html>
and for some reason whenever I try to access index.ejs, it returnes an error -
"username is not defined"
any idea what I'm doing wrong? the examples online looks exactly the same
thanks !
after Fadi Bitar answered this is how my server get event looks like and it's stil won't work:
app.get('/', function(req, res) {
if (req.session.user == undefined) {
// if user is not logged-in redirect back to login page //
res.render('login',{username:req.session.user});
} else {
console.log(req.session.user);
res.render('index', {username:req.session.user});
}
});
// about page
app.get('/login', function(req, res) {
res.render('login',{username:req.session.user});
});

In the initial code, it should work... Without seeing it my guess is that you are trying to echo <%=username%> in login.ejs.
Your updated code has a couple of points where you're using a variable that doesn't exist.
if (req.session.user == undefined) {
res.render('login',{username:req.session.user});
}
Here you're saying 'if req.session.user is undefined, set username to req.session.user' (undefined).
Then this bit does the same..
app.get('/login', function(req, res) {
res.render('login',{username:req.session.user});
});
I assume here that when you go to /login req.session.user is not set, so that's why that errors...

I believe you are missing the "username" variable in your get function.
Make sure you do:
res.render('/', {username: "example username"});

Related

using express csurf with ajax doesnt work

i am new with node js. i try to use csurf token with express using AJAX. here is my code
from server (app.js)
var cookieParser = require('cookie-parser')
var csrf = require('csurf')
var bodyParser = require('body-parser')
var express = require('express')
// setup route middlewares
var csrfProtection = csrf({ cookie: true })
var parseForm = bodyParser.urlencoded({ extended: false })
// create express app
var app = express()
app.set('view engine', 'ejs')
app.set('views', 'views')
// parse cookies
// we need this because "cookie" is true in csrfProtection
app.use(cookieParser())
app.use(express.static(__dirname + '/public'));
app.get('/form', csrfProtection, function (req, res) {
// pass the csrfToken to the view
res.render('send', { csrfToken: req.csrfToken() })
})
app.post('/process', parseForm, csrfProtection, function (req, res) {
console.log(req.body.name); // <--- it is doesnt show in my terminal
res.send('data is being processed')
})
app.listen(3000);
HTML (send.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">
<meta name="csrf-token" content="<%=csrfToken%>">
<title>Document</title>
</head>
<body>
<form>
<input type="text" name="name" value="Jhon Doe" class="inp-name">
<input type="submit" value="Send" class="btn-send">
</form>
<script src="/javascripts/script.js"></script>
</body>
</html>
JS file (script.js)
document.querySelector('.btn-send').addEventListener('click',
() => {
const name = document.querySelector('.inp-name').value;
// Read the CSRF token from the <meta> tag
const token = document.querySelector('meta[name="csrf-
token"]').getAttribute('content')
// Make a request using the Fetch API
fetch('/process', {
credentials: 'same-origin', // <-- includes cookies in the request
headers: {
'CSRF-Token': token // <-- is the csrf token as a header
},
method: 'POST',
body: {
name: name
}
})
});
when i try to run this i think it doesnt work because when i see in my terminal the name of Jhon Doe doesnt appears.
i try this example from this site http://expressjs.com/en/resources/middleware/csurf.html

MEAN stack app not working on Ubuntu (works in local)

I have developed a simple MEAN stack app (with Angular 4 for UI).
It works fine in my local Node, but when I deploy the same on Ubuntu it gives
Uncaught SyntaxError: Unexpected token < : in browser console
Here is my app.js content
const app = express();
const users = require('./routes/users');
const client = require('./routes/client');
// Port Number
//const port = 3000;
// Port Number
const port = process.env.PORT || 3001;
// CORS Middleware
app.use(cors());
// Set Static Folder
app.use(express.static(path.join(__dirname, 'public')));
// Body Parser Middleware
app.use(bodyParser.json());
// Passport Middleware
app.use(passport.initialize());
app.use(passport.session());
require('./config/passport')(passport);
app.use('/users', users);
app.use('/client', client);
// Index Route
app.get('/', (req, res) => {
res.send('Invalid Endpoint');
});
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'public/index.html'));
});
// Start Server
app.listen(port, () => {
console.log('Server started on port '+port);
});
My index.html under public folder
<html lang="en">
<head>
<meta charset="utf-8">
<title>MEAN</title>
<base href=".">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<!--Bootstrap and jQuery online links-->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<!-- For login Html -->
<link rel="stylesheet" href="assets/icons/simple-line-icons.css">
</head>
<body>
<app-root></app-root>
<script type="text/javascript" src="inline.bundle.js"></script><script type="text/javascript" src="polyfills.bundle.js"></script><script type="text/javascript" src="styles.bundle.js"></script><script type="text/javascript" src="vendor.bundle.js"></script><script type="text/javascript" src="main.bundle.js"></script></body>
</html>
Try changing: 'public' to: '/public', maybe the relative path helps?

Express not serving static files correctly for react build

I'm new to react. I've been trying to convert my MEAN stack app to an express and reactjs app but I'm having problems getting my build files to come in correctly. It looks like my server is loading my index.html file in place of my js files. Can anyone help me figure out why?
I've got the following error in my main.js in the browser: Uncaught SyntaxError: Unexpected token <
My files are built into a build folder which is a sibling to my server.js file.
mywebsite (root)
-src (f)
-build (f)
-server.js
-public (f)
Here's my server.js
require('./server/config/config');
// Get dependencies
const express = require('express');
const morgan = require('morgan');
const path = require('path');
const http = require('http');
const bodyParser = require('body-parser');
const api = require('./server/routes/api');
const compression = require('compression')
const app = express();
app.use(compression());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(morgan(':remote-addr - :remote-user [:date[clf]] ":method :url
HTTP/:http-version" :status :res[content-length] :response-time ms'));
// Serve static assets
app.use(express.static(path.join(__dirname, 'build')));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/api', api);
app.get('/robots.txt', function (req, res) {
res.type('text/plain');
res.send("User-agent: *\nDisallow: /");
});
// Always return the main index.html
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'build', 'index.html'));
});
const port = process.env.PORT || '3001';
app.set('port', port);
const server = http.createServer(app);
server.listen(port, () => console.log(`API running on
localhost:${port}`));
module.exports = app;
here's the generated index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-
fit=no">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="/brookeclonts/brookeclonts.com/manifest.json">
<link rel="shortcut
icon" href="/brookeclonts/brookeclonts.com/favicon.ico">
<title>React App
</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="text/javascript" src="/brookeclonts/brookeclonts.com/static/js/main.9ffbadeb.js">
</script>
</body>
</html>
Let me know if you see something I'm not seeing. I'm going in circles. Thanks in advance!
You can also merge directories as:
// Serve static assets
app.use('public', express.static(path.join(__dirname, 'build')));
app.use('public', express.static(path.join(__dirname, 'public')));
// Always return the main index.html
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'index.html'));
});
What was posted here was close to the answer. Thank you for your help everyone! My real problem was that I had forgotten about the .htaccess file. See: https://github.com/facebook/create-react-app/issues/1171 and https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#deployment

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');

Why is the directory throwing 404 when rendering ejs

I am trying to make a page which just receives a get request from my index.js file and just displays "hello user". I have created a 'users.ejs' file in my express app which just renders a string from a 'users.js' file. There is a form in my index.ejs file which redirects to my users directory. The index file works well when I type the '/' directory in the url box but for some reason, the file throws a 404 not found error in the browser when I hit the submit on the form in the first page instead of showing the 'users.ejs' page, can anyone tell me why it does this?
index.ejs
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p><br>
<form action='/users' method='get'>
Enter Name: <input type='text' name='thetext'></input><br><br>
<input type='submit' id='checkresponse'>enter</button>
</form>
<script type = 'text/javascript' src = '/dist/jquery.js'></script>
<script type = 'text/javascript' src = '/js/response.js'></script>
</body>
</html>
index.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Expr-Ass' });
});
module.exports = router;
users.js
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/users', function(req, res, next) {
res.render('users', {star:'Sparksiano'});
});
module.exports = router;
users.ejs
<!DOCTYPE html>
<html>
<head>
<title><%= star %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1>Welcome user!</h1>
</body>
</html>
Based off of comments below you may want to try something like this:
users.js
var express = require('express');
var router = express.Router();
/* Notice the path change */
router.get('/', function(req, res, next) {
res.render('users', {star:'Sparksiano'});
});
module.exports = router;
It sounds like you may be mounting your path to include a /users and then having a route that has a path of /users. Would be easier to troubleshoot if you posted the rest of the server side code.
I place the various ejs files in a folder and then point the express router to use that folder as a path:
var app = express();
app.set('port', 6000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
Then I route them to those pages:
app.get('/', function (req, res) {
res.render('index', {title: 'Express'});
});
app.get('/users', function (req, res) {
res.render('users', {star:'Sparksiano'});
});
Make sure the users.ejs page is in the same folder.

Resources