0

Let's say I have a button on my web page and an output-field. When I click on the button, an asynchronous function is called several times. Each time, the function returns some data, which I want to send to the output field (and append to the previous data).

Here is the main.js:

$(document).ready(function () {
$("#submitButton").on('click', function () {
        $.post(
            '/',
            {
                text: inputField.val(),
                depth: $('#depthField').val()
            },
            function (response) {
                let outField = $('#outputField');
                let txt = outField.text().trim();
                outField.text(txt + "\n new data: " + response);
            }
        );
    });
}

And then I have a index.js:

router.post('/', function (req, res) {
    let text = req.body.text;

    getHTML(text, function (buf) {
        doParse(buf, function (out) {
            res.send(out);
        })
    });
});

getHTML returns some data, which is proceeded by doParse. The doParse also generates some data, which should be parsed back to the output-field.

I guess, the post-method is not the right way, to do this, because it is only called once?

EDIT 1:

The Problem is, that i can only see the first data, which is send by the callback, then i get an

(node:16436) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Can't set headers after they are sent.

EDIT 2:

Principal working of the 2 functions 'getHTML' and 'doParse' :

const getHTML = function(callback) {
    for (let j = 0; j < 10; j++) {
        callback(j);
    }
};

const doParse = function(buf, callback) {
    let msg = 'val = ' + buf;

    console.log(msg);
    callback(msg);
};
Soro
  • 61
  • 8
  • post is fine - what is the nature of your difficulty? You haven't really described a problem you are having – Jaromanda X Jan 29 '17 at 11:31
  • as @JaromandaX mentioned please describe your problem in more detail but you should use .end() in your nodejs doParse callback to send the response back: https://nodejs.org/api/http.html#http_response_end_data_encoding_callback – Jörn Jan 29 '17 at 11:38
  • As edited above, I always get an 'Can't set headers after they are sent' error. – Soro Jan 29 '17 at 11:49
  • @Soro How often gets the doParse callback called per request? Just once? – Jörn Jan 29 '17 at 11:56
  • No, i gets called several times ... I upload some sample-code to show, how it works in principal – Soro Jan 29 '17 at 12:01
  • @Soro then you should use .write() instead of .send() https://nodejs.org/api/http.html#http_response_write_chunk_encoding_callback – Jörn Jan 29 '17 at 12:02

1 Answers1

0

You should use .write() instead of .send() as already described here.

as .send() is just a wrapper for res.write(); res.end() don't forget to end the response with .end() manually after you're done.

Jörn
  • 845
  • 5
  • 16
  • But i want to send the data to the output-field every time, doParse is called. So, i don't want to collect the data and then send all at once. – Soro Jan 29 '17 at 12:10
  • @Soro see https://stackoverflow.com/questions/9751711/streaming-http-responses-with-nodejs – Jörn Jan 29 '17 at 12:23
  • The only thing, i found on this page, was to set the header correspondingly, but nothing changed: res.writeHead(200, { 'Connection': 'Transfer-Encoding', 'Content-Type': 'text/plain; charset=utf-8', 'Transfer-Encoding': 'chunked', 'Cache-Control': 'no-transform', 'X-Content-Type-Options': 'nosniff'}); Working on google-chrome, i can see the incoming messages in the 'network'-tab at the inspector, but they only get rendered at 'res.end()' – Soro Jan 29 '17 at 13:33
  • @Soro i think it's jquery post callback, that gets called on stream end. i used .write in several server-server apps to stream data from one endpoint to the other. maybe you'll look into someting like https://stackoverflow.com/questions/7740646/jquery-ajax-read-the-stream-incrementally ang jquery stream handing as well. – Jörn Jan 29 '17 at 16:16