Unable to render error page in ejs using nodeJS - node.js

I want the class to be activated when the path === '/' else ''.I used ternary operator to activate the class. the class is in active state when the path is equal but when the path is not equal it is unable to render the error page that i given
<header class="main-header">
<nav class="main-header__nav">
<ul class="main-header__item-list">
<li class="main-header__item"><a class="<%= path === '/' ? 'active' : '' %>" href="/">Shop</a></li>
<li class="main-header__item"><a class="<%= path === '/admin/add-product' ? 'active' : '' %>" href="/admin/add-product">Add Product</a></li>
</ul>
</nav>
the code runs fine if it is equal to the path but if it is not equal that when i want to render a error page
check this image for error message

First, omit the .ejs in your include statements:
<%- include('includes/navigation') %>
<%- include('includes/end') %>
Next, on your app.js, you will need to pass the path as context to the view:
app.get('/', function(req, res) {
const path = '/';
res.render('somePage', {path:path});
});
app.get('/admin/add-product', function(req, res) {
const path = '/admin/add-product';
res.render('somePage', {path:path});
});
Now, you shouldn't get the 'path is not defined' error.
Hope that helps!

Related

How do i make the ejs variable work that i send from nodejs?

I am tring to get a variable that i send from nodejs to ejs to work. But for some reason it wont, i cant figure out why.
This is the index.js:
var newOne = "Yes"
router.get('/main', ensureAuthenticated, (req, res) =>
res.render('main', {
user: req.user,
newOneInView : newOne
})
)
And this is in the main.ejs file:
<%if (newOneInView == "Yes") { %>
document.getElementById("avatar").src = "/static/images/Apocaliptic1.png";
<% } %>
So what i am trying to achieve is that variable will be seen from the nodejs at the main.ejs page but some reason it wont change the image SRC. What am i doing wrong here?
In your template you need to make sure that you place the code for changing the src attribute in a script that is placed after the element (alternatively you can use a listener for the content to be loaded), e.g:
<body>
<img id="avatar" src="/some-other-path"/>
<script>
<% if (newOneInView === "Yes") { %>
document.getElementById("avatar").src = "/static/images/Apocaliptic1.png";
<% } %>
</script>
</body>

How do I store a variable for every route in Express.js?

So I'm building a simple authentication application and I'm using express-sessions to do this. For the UI, I need to display in the nav-bar a button for logging in, if the user hasn't done so already, and a button for logging out if they are already logged in.
The problem is, I'm not sure how to store this state across all of my routes, without using the same code for each route. Currently I've got this on the index route, which works fine:
/* GET home page. */
router.get('/', function(req, res, next) {
var logged_in = false;
if (req.session.userId) {
logged_in = true;
}
res.render('general/index', { is_logged_in: logged_in});
});
And in the nav-bar I display the buttons dynamically like so:
<% if( is_logged_in){ %>
<li class="nav-item active">
<a class="nav-link" href="/users/logout">Logout<span class="sr-only">(current)</span></a>
</li>
<% } else { %>
<li class="nav-item active">
<a class="nav-link" href="/login">Login<span class="sr-only">(current)</span></a>
</li>
<% } %>
But the problem is, I have to use the same code for each route if I want this to work for the nav-bar, which goes against DRY coding practices. How do I display this button dynamically without having to repeat the same bit of code on each route, checking if a user session ID exists? Do I set a global variable? I'm new to Express so all help appreciated. Thanks
You can setup a middleware to set the login status and use the res.locals for the lifetime of the request.
function checkLoggedIn(req, res, next) {
var logged_in = false;
if (req.session.userId) {
res.locals.logged_in = true;
}
}
You can then mount it for all the routes or chain it for some routes:
// all routes after this middleware:
app.use(checkLoggedIn)
// chain it
app.get('/mypath', checkLoggedIn, (req, res) => { ... })
res.locals are available to view as well so you can do the following without passing during render.
// You can simply render
res.render('general/index');
// logged_in variable is available to view
<% if(logged_in){ %>

Unable to display flash message in view with ejs template

I am a newbie in NodeJS. I have a problem that I am unable to show flash message in my view.
Here is my Controller,
index : function(req, res){
res.locals.flash = _.clone(req.session.flash);
res.locals.layout = false;
res.view('login');
},
login : function(req, res){
....
if(!admin){
req.session.flash = {
err : 'User is not found.' // My flash message
}
res.locals.layout = false;
res.redirect('login');
return;
}
.....
}
Here is my view,
<% if(flash && flash.err) { %>
<div class="alert alert-danger">
<% JSON.stringify(flash.err) %>
</div>
<% } %>
When login is false, it show only an empty alert box.
And I have a second problem. When I refresh page, The alert box isn't disappeared.
Could someone help me please.
Thanks a lot.
The alert box keeps on appearing because the req.session.flash object persists the session, so you need to null that out once it's used, or you can just simply use req.flash(), which does that for you. So change your index method to something like this:
index: function(req, res) {
// req.flash() returns the contents of req.session.flash and flushes it
// so it doesn't appear on next page load. No need to clone.
res.locals.flash = req.flash();
res.locals.layout = false;
res.view('login');
},
Now, onto the second problem. The error messages aren't appearing because you aren't using the proper EJS syntax to output escaped values into the view. All you need to do is change your code to this:
<% if(flash && flash.err) { %>
<div class="alert alert-danger">
// Change <% to <%=
<%= flash.err %>
</div>
<% } %>
No need to JSON.stringify, unless you like the quotes. Notice that I changed the <% to <%=, which in EJS means "escape this and output it". It's not template HTML or anything like that, so it's okay to escape it anyway.

How to do conditional includes of partials in hoganjs with expressjs? (using hogan-express module)

I'm using express 3.0.x with hogan-express as template engine to build a single page application.
I would like to add a partial that will contain information that will help me to develop / debug the application. (I am also working with angularjs)
Depending on a variable somewhere in my app, like "devMode = true" I'd like to include this particular partial and it won't be included if "devMode = false".
Here are my files
index.js (routes):
exports.index = function(req, res) {
res.locals = {
template_engine: 'HoganJS'
}
return res.render(
'index',
{
partials:
{
head: 'head', foot: 'foot'
}
}
);
};
exports.partials = function(req, res) {
res.render('partials/' + req.params.entity + '/' + req.params.name)
}
index.html:
[[> head]]
<div class="navbar fixed-top">
<div class="navbar-inner">
<a class="brand" href="/">My app</a>
<ul class="nav">
</ul>
</div>
</div>
<div class="container">
<div ng-view></div>
</div>
[[> foot]]
(I changed {{ }} to [[ ]] to resolve conflict with angularjs syntax)
I'd like to include something like [[>dev]] before [[> foot]] depending on a boolean somewhere in my app.
Thank you for any help:)

express + ejs login widget

I am trying to make easy widget for buttons login/logout.
laout.ejs
<% include ../shared/login_logout %>
login_logout.ejs
<% if ( !common.IsDefined(membershipHelper.GetCurrentUser(request , response)) ) { %>
<li class="pull-right">Login</li>
<% } else { %>
<li class="pull-right">Log Out</li>
<% } %>
membershipHelper.GetCurrentUser - this method checks request session for user_id and if it finds it returns user if it is found in db(mongoDB) else it returns null. As user is returned in callback function of User.findById ejs file receives "undefined" always. I thought to put this GetCurrentUser in the middleware but it look like I can't set null or undefined to locals variable
What can be solution for this problem?

Resources