How to res.render/send a variable after a redirect? - node.js

I want to send a message variable that says something like succeeded or failed wihtout the use of passport or sessions.
When it fails I can just do this:
res.status(401).render('register', {
message: 'Your username/email or password is incorrect.'
})
So I was thinking this was possible:
res.redirect('/');
res.render('', { message: 'Login success.'});
But it turns out it isn't:
Error: Cannot set headers after they are sent to the client
Are there any simple sollutions?
I tried making a router.get('/message/redirect :route') but I realised I ran into the same problem there too.

You are redirecting before rendering. So the render method can't send headers because you have already redirected them. You need to call either redirect or render, not both at once. you can do it like this.
res.render('/', { message: 'Login success.'});
remove this line
res.redirect('/');
In your EJS file just call <%= message %> to access the message. There is a better way of dealing with confirmation/error messages. Use Flash.
npm install express-flash
Then before rendering, call the flash. Flash takes two arguments, a name of the message and the message itself, Like this
req.flash("MessageName", "Login success");
res.redirect(pathName);
Make sure to use flash
const flash = require('express-flash');
app = express();
app.use(flash());
app.use((req, res, next) => {
res.locals.MessageName= req.flash("MessageName");
next();
});
To access the message in EJS file just call <%= MessageName %>
Here is sample from my code:
In the server file:
req.flash("error", "Something went wrong");
res.redirect('back');
In the EJS file:
<div class="flash">
<% if(error && error.length > 0){ %>
<div class="flash_error">
<h1 class="flash_error--text"><%= error %></h1>
</div>
<% } %>
</div>
Read this for more information

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.

Display flash message from router to a ejs view

I am setting up flash message to be displayed on view whenever the message is sent from the router to the view
if (err) {
console.log(err);
} else {
req.flash('success', 'You are now registered and can Log in')
res.redirect('/users/login');
// res.render('users/login',{
// success_message:'Account created successfully'
// });
}
is there a way to get this displayed on the view when the page loads without having to do it manually as the one commented, because that one works, but I'd like to get it automatically shown. I have checked some submissions available on the forum, I am still not able to find one that really gets the message displayed
use connect-flash for the session used for storing messages.
const flash = require('connect-flash');
Use middleware in express js
app.use(flash());
Append flash message in request render
res.render('/users/login', { message: req.flash('Restistration succesfully.') });
To show the flash message in html/ejs
<% if (message.length > 0) { %>
<div class="alert alert-danger"><%= message %></div>
<% } %>

Passing req.user to template not working with ejs and express

I am using EJS and Express to take and check if the current user exists and if not show one thing instead of the other. My issue is that I am setting req.user to res.locals.currentUser but it is not passing through to the template so I can output it as well as check if it exists.
in my app.js
app.use(function(req, res, next){
res.locals.currentUser = req.user;
next();
});
my ejs file
<% if(!currentUser){ %>
<li>Login</li>
<li>Sign Up</li>
<% } else { %>
<li>Signed In As <%= currentUser.email %></li>
<li>Profile</li>
<li>Logout</li>
<% } %>
This evaluates always to false therefore showing the first section of the if statement.
What is wrong here to make it so I can't test or see the user data in my ejs view? When I console.log the currentUser is returns undefined.
Some information that might be important, I am using a redis session store instead of mongo store. I also am using body-parser not cookieparser.
I was facing the same issue while using Passport in node.js with ejs templating.
The solution is to place it below the passport lines of code( that is serialize and deserialize).
These functions are responsible for saving the user to "req.user", and thus if the app.use is placed above it, the code won't work as req.user is null until this.
Adios

Render app views per user agent in EJS

I'm working on a Node.js/Express that uses EJS and trying to render certain views on desktop or mobile.
I've added the following middleware to return the user agent in my app.js:
app.use(function(req, res, next) {
res.locals.ua = req.get('User-Agent');
next();
});
Next, if I echo <%= ua %> in my view, I successfully get the user agent, but I'm not sure how to actually check specific agents.
I tried <$ if(ua.match(/iPhone)) { %> as a quick example, but got a syntax error. Any help would be appreciated!
Several errors:
1) You started with a $ inside your embedded script. You should instead use a %.
2) You need to close out your regex with a /.
Something like this:
<% if(ua.match(/Intel/)) { %>
<%= ua %>
<% } %>

How do you test req.flash() in express?

I currently have an express/node application I want to test, and but responses that it gives are in the form of req.flash('warn', 'message goes here');
Unfortunately, the documentation on express.js does not describe how this message travels to the client very thoroughly.
I know expresso has an assert.response() function that tests response objects. I was wondering where the flash message goes, and how I can test it in a similar way (or if it's not possible, and I should be sending everything through the response object).
i don't think this is supposed to work like that. you can't just use req.flash()as your only way to respond to a request.
it's more like an easy way to flash messages to the user on your normal templates - e.g. after inserting/creating an article you can either say:
req.flash('error', 'could not insert because .... ');
or
req.flash('info', 'article added successfully!');
for my last project i then added two dynamic helpers to my app:
app.dynamicHelpers({
info: function (req, res) {
return req.flash('info');
},
error: function (req, res) {
return req.flash('error');
}
});
so that i can just say sth like this in my view:
<% if (info !== undefined && info != "") { %>
<div class="infoBubble">
<%= info %>
</div>
<% } %>
<% if (error !== undefined && error != "") { %>
<div class="errorBubble">
<strong>Fehler</strong>: <%= error %>
</div>
<% } %>
result looks like this:

Resources