showing a message as javascript alert after logout - node.js

app.get('/logout', function (req, res) {
delete req.session.auth;
res.status(200).redirect('/');
});
I am using this for redirecting page after logout. I need to show an alert box when logout is done.Please suggest

This depends on what packages your using. You don't state it so i'll give my two cents with the EJS approach
if you use connect-flash its as simple as :
app.get('/logout', function(req, res) {
delete req.session.auth;
req.flash('message', 'YourMessageHere')
res.redirect('/login');
});
And then when you render it check for the variable like this:
<div>
<%if(message){%>
<%= message%>
<% } %>
</div>
Or you can render the page and pass data along as a json object:
app.get('/logout', function(req, res) {
delete req.session.auth;
res.render('./link/to/html/file', {message: 'Your Message here'});
});
And again in the html check for the variable being passed in.
Look at the res object and see what its capable of and whatever frameworks your using look and see how data can be interpreted.

Maybe you can send a parameter to the redirected page, and, on that page evaluate if the parameter is present or not in order to display the corresponding alert:
app.get('/logout', function (req, res) {
delete req.session.auth;
res.status(200).redirect('/?msg=session%20destroyed');
});
in the '/' logic, you can do something like:
app.get('/', function(req, res) {
var message;
if(req.query.msg){
message = req.query.msg;
}
// other logic here...
res.send(message); // or res.render('index', { msg: message, //other properties...
});
}
You may adapt this depending on the view engine you're using.
Another option, instead of redirecting, send the logout request through ajax, in the server, after destroying the session, response with an 'ok' or '1' status. Then, evaluate the ajax response in order to display the alert in the same page and implement all the corresponding logic on the front (like clearing all forms, displayed info available only when an active session exists, etc).
Express:
app.get('/logout', function (req, res) {
delete req.session.auth;
res.status(200).send('1');
});
In the front (assuming you're using jQuery):
$.get('/logout', function(response){
if(response == '1'){
alert('Successfully logged out!');
// Destroy DOM objects that should not be still available.
}
});
It depends on what's more easy for you to acomplish, the logic in your page and your requirements.

Related

How to run function with this function

How to run function within a function
If the first function throw any error then 2nd function should run
server.post('/User', (req, res,next) =>
server.post('/submit', (req, res) =>
server.post('/User', (req, res,next) => {
// Some Task
if(){
//Do something
}
else {
server.post('/submit', (req, res) => {
If the first function returns a promise you could run those functions after catching the error like this:
firstFunction()
.catch(e => {
secondFunction();
});
Otherwise you could use a try-catch statement like this:
try {
firstFunction();
} catch (e) {
secondFunction();
}
In Express, the next parameter allows a route/middleware to pass processing to the next route/middleware (actually, all routes are merely middlewares that don't call next). Therefore you can implement passing your route processing by just calling next():
function submitHandler (req, res) {
// ...
}
server.post('/User',
(req, res, next) => {
if(/* all ok */){
//Do something
}
else {
next(); // continue processing
return;
}
},
submitHandler // continue with this function
)
server.post('/submit', submitHandler); // also have a separate endpoint where
// submitHandler can be accessed directly
Remember that server.post(...) doesn't actually carry out that operation in that route. It just registers a route handler for some future route. So, you don't generally do things like:
server.post("/firstRoute", function(req, res, next) {
if (some condition) {
server.post("/secondRoute", ...);
}
});
This would configure a second route handler for all users based on what one user did in their /firstRoute request.
Remember a server contains a set of route handlers that work for ALL users that will use the server now and in the future. What your code proposes is that based on some data in one particular incoming request, you would change the routes that the server supports for all users. That's not how you would code a server.
If you need to maintain server-side state for a particular user such that data from one request influences how some future request works, then you would typically create a user session object, store the state for that user in the session and then one some future request, you can consult the data in the session to help you respond to the future request.
A simple example would be a shopping cart. Each time you add something to the cart, the data is added to the session object. Then, when the user asks to view the cart, you render a page by consulting the items in that user's session object. If they then ask to "check out", you purchase the items in the cart for them. You don't register and deregister routes for "view cart" and "checkout". Those routes are always registered. Instead, you use the data in the session object to help you process those requests.
If you want to run the same code from several different routes, then you just move that code into a shared function and call that shared function from more than one route handler.

Delete a user with Mongoose, Express

I am new to Express and MongoDB. I created a small web app in Node.js and am using Express.js and Mongoose. I can succesfully create a user and have a user sign in but I am having trouble with a user being able to delete their account.
I have a user.js file in my routes folder which is where I am writing the code to signup, signin, delete, etc. Here is a link to the project on GitHub ( https://github.com/NicholasGati/shopping-cart-2 ). The button to delete a user's account is in views/user/edit.hbs. I put the button in a form. When I click the button, the user is not deleted and I am redirected to '/' for some reason. Note: '/:id' in my routes/user.js file becomes '/user/:id'.
Here is the code in the routes/user.js file for the delete method:
router.delete('/:id', isLoggedIn, (req, res, next) => {
User.findOneAndRemove({_id: req.params.id}, (err) => {
if (err) {
req.flash("error", err);
return res.redirect("/user/edit");
}
req.flash("success", "Your account has been deleted.");
req.logout();
return res.redirect("/shop/coffee");
});
});
Here is the form in views/user/edit.hbs:
<form action="/user/{{user.id}}" method="delete">
<div class="form-group">
<button type="submit" class="btn btn-danger">Delete Account</button>
</div>
</form>
Also, here is the isLoggedIn function:
function isLoggedIn(req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect("/");
}
Since you are new I think I should lead you to find the problem yourself:)
Make sure about form methods.
Make sure the route for user deletion is called.
If the markup doesn't seem right I am sorry cas I am using my phone to post this answer.
I had this exact same issue. I used an XMLHttpRequest from the client side in order to do this. I'm sorry I'm not experienced enough to explain why it worked this way and not from the node end, but it may have to do with form data being inherently designed to pass information, not delete information. In any case, try this solution.
In your client side code:
Your button code (form action shouldn't matter, and for that matter, the tag shouldn't either, since the logic is handled in the JS, but this is what I used):
<button id = "del-btn" class="btn btn-danger">Delete</button>
Script to send HTTP request from the button click, this code should go in the same file as your button above, or as an include JS file that the HTML page has imported:
<script>
var del_btn = document.getElementById("del-btn");
del_btn.addEventListener("click", function(e) {
var user = <%- JSON.stringify(user) %>;
var xhr = new XMLHttpRequest();
xhr.open("DELETE", "/user/" + user._id);
xhr.onreadystatechange = function () {
if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
console.log(xhr.responseText);
window.location.href = "/users";
}
};
xhr.send();
//make XMLHttpRequest to delete the poll here
}, false);
</script>
in your server side route, note how the response is just a success code. It's the XMLHTTP Request from the client side that does the redirection:
app.delete('/user/:id', isLoggedIn, function(req,res){
User.remove({
_id: req.params.id,
ownerID: req.user._id
}, function (err, user) {
if (err)
return console.error(err);
console.log('User successfully removed from polls collection!');
res.status(200).send();
});
});

Change the order of a routes variable in the front end NodeJs/Express/Jade

Novice to NodeJS and Express but lets say I have this route for mywebsite.com/tournaments.
router.get('/tournaments', function (req, res) {
TournamentController.getAllTournaments(function (err, docs) {
if (err) {
//render error
} else {
res.render('tournaments', {
data: {
title: 'mysite',
command: 'tournaments',
user: req.session.user,
tournaments: docs
}
});
}
});
});
data.tournaments is an array of tournaments in order of their date. Lets say in the front end I have a select/option form where the user can choose date/prize/players as the order to sort the tournaments by. How can I sort the data.tournaments without having to call another route or refresh the page? I'm using Jade on the front end.
You can always sort them directly in the Browser via Javascript, either do it yourself or use a plugin like datatables.
If you don't wanna do that but do it on the server, you'll need an ajax call for that and a route that handles the sorting (based on the parameters you pass), and afterwards change the DOM according to the response. This goes without refreshing the page, but you'll need a route for that, or change the existing route and extend your controller to take optional parameters, something like
router.get('/tournaments/:sort?', function (req, res) {
TournamentController.getAllTournaments(req.param('sort'), function (err, docs) {
/* ... */
});
});

Unable to call views

I'm using Sails and when I attempt to call the login action of my UsersController the view response is not getting loaded. I know my routing is working, because the console.log successfully logs both the loginpassword and loginname. However, the res.view() doesn't work. Neither does returning res.view().
module.exports = {
create: function(req, res) { },
destroy: function(req, res) {
},
login: function(req, res) { var loginname = req.param("loginname");
var loginpassword = req.param("loginpassword");
console.log(loginname + ' ' + loginpassword);
res.view();
},
logout: function(req, res) {
},
_config: {}
};
I have a /views/user/login.ejs and all it currently contains is a header block with some test text, but I can't get that to render at all. Any thoughts?
Edit:
I've noticed that when I look at my Chrome developer tools and I view the Response portion of the Network tab, I've actually getting my view loaded back into the layout <%-body%> but the page itself is not loading the returned view. Is this a bug or am I doing something stupid? I'm on the latest stable.
Here's the code: https://github.com/FreefallGeek/SailtsTest
The problem seems to be that you are using a jquery.post which is a ajax request and you simply don't render the response.
http://api.jquery.com/jquery.post/
You might want to use a form and optionaly submit the form by js/jquery.
Alternatively you need to render just partial html in the success function of jquery.post

Response headers of previous request affecting current request

The following code is the user-facing part of a new node app we are building:
var loadInvoice = function(req, res, next) {
Invoice.findById(req.params.invoiceId, function (err, invoice) {
if (err) {
res.send(404, 'Page not found');
} else {
req.invoice = invoice;
next();
}
});
};
app.namespace('/invoices/:invoiceId', loadInvoice, function () {
app.get('', function(req, res){
var templateVals = {
//some template data
};
res.render('paymentselection', templateVals);
});
app.post('', function(req, res){
var data = {
// some data for the apiCall
};
someAPI.someRequest(data, function(err, data) {
console.log(res.status());
res.redirect(data.url);
});
});
});
The first method returns a confirmation page where the user presses a button to post to the same url, which triggers a redirect to an external website.
This all works exactly once. Every second request will crash the app with the message Cant set headers after they are sent. After carefull inspection of the code I could find no reason for this to happen so I added the console.log line which indeed confirms the location header has been set. But it is set to the value i got from someAPI on the previous request not the current one.
This makes absolutely no sense to me. I do not store this value anywhere nor do I do caching or persistence of this data in any way.
Does anybody know what could be causing this?
I use express, express-namespace, mogoose and swig
I found out the problem was being caused bij the 'Restler' libaray used within 'someAPI'. I have no idea how this is possible but swapping it out with something else fixed the problem.

Resources