Question

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')
Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top