0

I have this code snippet.

function handleRequest(req, res)
{
    req.on('data', parseInput);
    res.write(generateInputform());
}

http.createServer(handleRequest).listen(port, ipAddress);

The req.on callbacks parseInput and does literally what the function's called, it parses the input and sets pins and such. Afterwards another input form is generated and presented to the user.

However, node.js generates the input first and then parses the input... This means the user has to refresh the page to reflect the given commands. Parsing input works, I can see the pins toggle on submit with my logic analyzer.

I seem to be stuck in a rut as I cannot find a simple solution to this answer. The ones that show promise deal with asynchronous delaying which I'd rather avoid.

Perhaps someone can shed a light on this issue?

Here's the complete handleRequest.

function handleRequest(req, res)
{
    switch( req.url )
        {
            case "/markings.css" :
                res.writeHead(200, {'Content-Type': 'text/css'});
                res.end("Literally nothing right now");
                break;
            case "/json" :
                res.writeHead(200, {'Content-Type': 'text/json'});
                res.end(encapsulator(J17_1, J18_1, J19_14, J20_14));
                break;
            case "/index":
                res.writeHead(200, {'Content-Type': 'text/html'});
                res.end(getHTML());
                break;
            case "/":
                // show the user a simple form
                console.log("[200] " + req.method + " to " + req.url);
                res.writeHead(200, "OK", {'Content-Type': 'text/html'});
                switch( req.method )
                    {
                        case 'POST':
                            //Problems between here
                            req.on('data', parseInput);
                            res.write(generateInputform());
                            //And here
                            console.log("Done");
                            res.end();
                            break;
                        case 'GET':
                            console.log("User probably refreshed page without entering anything useful");
                            res.write(generateInputform());
                            console.log("Done");
                            res.end();
                            break;
                        default:
                            console.log("?");
                            res.end();
                            break;
                    }

                //res.end();
                break;
            default:
                res.writeHead(404, {'Content-Type': 'text/html'});
                res.end('<!DOCTYPE html>\r\n<html>\r\n<body>\r\n404, that means trouble.<br><a href="http://' +
                        ipAddress + ':' + port + '">Go back to the index</a></body></html>');
                break;
        }
}

Edit:

Answer found here. Make a blocking call to a function in Node.js required in this case?

New handleRequest

req.on('data', parseInput);
req.on('end', function()
{
    res.write(generateInputform());
    console.log("Done");
    res.end();
});
Nos
  • 133
  • 7

3 Answers3

1

This is because Node.js (and javascript) runs asynchronously and not synchronously as you are probably used with other languages. This means that while a thread is performing I/O operations in the background the main thread is allowed to run. So in your case the "generateInputform()" is performed while the input is still being parsed.

The solution to your problem is to use callbacks. I suggest you to read this tutorial to understand the concept: http://www.tutorialspoint.com/nodejs/nodejs_callbacks_concept.htm

ilbonte
  • 151
  • 1
  • 2
  • 10
  • I somewhat understand the idea, but I'm not really sure how to apply callbacks without having to rewrite quite a bit. Doesn't this mean I have to callback generateInputform, res.write and res.end to make this work? – Nos May 15 '16 at 14:33
1

You are only defining what happens when the req object receives data:

req.on("data", parseInput);

This is executed directly:

res.write(generateInputform());

generateInput probably needs to go inside the parseInput.

Aleksander Azizi
  • 9,829
  • 9
  • 59
  • 87
  • I think that nests the code unnecessarily. Might be wrong though. – Nos May 15 '16 at 14:18
  • Shoot, I took too long to update the main post... I added the complete function. Point is, it's in a switch case, these two commands can only be executed when req receives data. Or, at least, should be, unless I read things wrong. – Nos May 15 '16 at 14:24
1

You are still saying "when you receive data, do this" followed by "now do that". The "now do that" will be executed directly, while the first one only means it is waiting for data. The event that you will receive data happens a lot later, probably in the next loop. (no clue how node does it exactly)