0

Is there a way to emit to the current socket within a post method of node.js using socket.io and express without having to go through the io.sockets.on('connection')?

Here is my issue. I am making a mini authorization system. When the user submits from the form it post the data through '/login' instead of using a onclick emit. If the user has an invalid user-name or password it should send a message back notifying it failed. I would prefer not to use the callback or write because I am using a Jade template. You can see my source code here.

Example: Server Side

var LoggIn = require('./lib/login.js'); // <-- Middle-ware app.post('/login', function (req, res){ LoggIn.authenticate(req.body.user, req.body.password, function(user, msg) { if (user) { req.session.user = user; res.redirect('/'); } else { res.render('login'); //res.emit('loginFail', 'You have entered an invalid user / password!<br>Try Again.); // <-- wishing for something like this console.log('Login Failed! : ' + msg); } }); }); 

Example Client Side

JS

var status = document.getElementById('status'); socket.on('loginFail', function(msg) { status.innerHTML = msg; }); 

Jade Form

#status form#loginForm(method='POST', action='/login') input(name='user', placeholder='User Name') br input(name='password', placeholder='Password', type='password') br input(value='Sign In', type='submit') 
2
  • 1
    Instead of using res.emit have you tried using the socket that was initialized on the server? Example: socket.emit('loginFail','Can't log in'); Also I don't know if you can use sockets for this as the client would still need to connect after rendering the page, in which they would miss the emit. Is there a reason you can't do something like this res.render('login',{error:'Invalid credentials'}); and then display the status if it exists Commented Jun 23, 2013 at 15:19
  • I never even thought to try and pass the data with the render method. Jade and Node.js are still pretty new to me so I really appreciate the advice. Commented Jun 24, 2013 at 1:59

1 Answer 1

1

I don't think that there is a way to do this without using io.sockets.on('connection') again. If you're using res.render anyway, you could pass data through that though:

res.render('login', {msg: 'You have entered an invalid user / password!<br>Try Again.'}); 

and then do something like this in your jade doc to print out the message if it exists:

- if (msg) p #{msg} 

But the problem with doing that is that it reloads the page, which I don't think you want if you're just trying to display a simple feedback message. You could use jQuery to submit the form on the client side instead:

 $('#myForm').submit(function(e){ e.preventDefault(); $.post( $(this).attr("action"), // The URL to send form data to $(this).serialize(), // Serializes the form data to be sent // Success callback function function(data){ if(data.url){ window.location.href = data.url; } else{ $('#msg').html(data.msg); } } ); }); 

On the server-side you would have:

app.post('/login', function(req, res){ // do whatever you need to check if the login is valid if(validLogin){ res.send({url: myURL}); // send url that user should be redirected to } else{ res.send({msg: 'You have entered an invalid user / password!<br>Try Again.'}); } }); 

So if the login is valid, the URL to redirect is sent back to the browser and the user is redirected. If the login is not valid, the error message is sent back and is displayed. Check out this question for more about submitting a form and then redirecting via jQuery.

Sign up to request clarification or add additional context in comments.

1 Comment

Actually I think your first suggestion is a good one. I am not minding a page reload with such little content and there is also some path configurations that rely on what I have done. For my main pages I think you have a good point though. Thank you for your feedback.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.