You are reading a single comment by @Gordon and its replies. Click here to read the full conversation.
  • Right - I think I see what's going on...

    The flow of execution goes something like this:

    • Web Browser POSTs the request
    • onPageRequest is called - at this point the headers are received, but the POSTed data isn't
    • handlePOST is called - which sets up handlers for the data coming down the connection and then finally handles that data when the connection closes.
    • handlePOST returns
    • The remainder of onPageRequest is executed and serves up the page
    • When the connection closes, the 'close' handler from handlePOST finally gets called and updates the state.

    So actually if you want to receive all the data and then send out the new page, you can use the end event in handlePOST rather than close.

    I tweaked the main bit of code to do what I believe you're after here:

    var postData = {};
    
    function sendPage(res) {
      // We're using ES6 Template Literals here to make the HTML easy
      // to read.
      var d = `
    <html>
     <body>
      <form action="#" method="post">
        <label for="mytext">Some text to send:</label>
        <input type="text" id="mytext" name="mytext" value="Testing"/><br/>
        <label for="led1">LED1 (red):</label>
        <input type="checkbox" id="led1" name="led1" value="1" ${postData.led1?"checked":""}><br/>
        <label for="led2">LED2 (green):</label>
        <input type="checkbox" id="led2" name="led2" value="1" ${postData.led2?"checked":""}><br/>
        <button>Submit</button>
      </form>
     </body>
    </html>`;
      res.writeHead(200, {'Content-Type': 'text/html', 'Content-Length':d.length});
      res.end(d);
    }
    
    // This serves up the webpage
    function onPageRequest(req, res) {
      var a = url.parse(req.url, true);
      if (a.pathname=="/") {
        // handle the '/' (root) page...
        // If we had a POST, handle the data we're being givem
        if (req.method=="POST" && 
            req.headers["Content-Type"]=="applicatio­n/x-www-form-urlencoded")
          handlePOST(req, function() { sendPage(res); });
        else
          sendPage(res);
      } else {
        // Page not found - return 404
        res.writeHead(404, {'Content-Type': 'text/plain'});
        res.end("404: Page "+a.pathname+" not found");
      }
    }
    
    // This handles any received data from the POST request
    function handlePOST(req, callback) {
      var data = "";
      req.on('data', function(d) { data += d; });
      req.on('end', function() {
        // closed - now handle the url encoded data we got
        postData = {};
        data.split("&").forEach(function(el) {
          var els = el.split("=");
          postData[els[0]] = decodeURIComponent(els[1]);
        });
        // finally our data is in postData
        console.log(postData);
        // do stuff with it!
        console.log("We got sent the text ", postData.mytext);
        digitalWrite(LED1, postData.led1);
        digitalWrite(LED2, postData.led2);
        callback();
      });
    }
    

    (I also send a Content-Length header as it looks like on recent Espruino builds that may be needed to work nicely with Chrome)

  • Thank you Gordon, I tried with your changes and it now works as expected. I will try to apply this to my project that involves monitoring and controlling a battery charger. I want to be able to read battery voltage and charge current, display the readings in a table in the web browser and set the charge current and charge voltage remotely. I am using for example the LED1 output to turn the charger on and off. So I was struggling with trying to understand why the webpage would show data that was not updated. I intend to share the code when it is more functional, there may be other people trying to do something similar.

About

Avatar for Gordon @Gordon started