kami1991
kami1991

Reputation: 27

Pushing async Data to View in NodeJS

So my problem is that I need to push some data from an HTTP GET Request to a view and I've no clue where to start in Node.js.

What I got til now, is:

var1 = 0;
var2 = 0;

some async HTTP GET Request -> {
    success: {
       var1 = 1;
    }
}

some async HTTP GET Request -> {
    success: {
       var2 = 2;
    }
}
res.render('index/asd', {var1: var1, var2: var2}) --> //Output var1/var2 = 0

Can I push data after async request without to wait for it? Something like res.update(blabla)?

Upvotes: 0

Views: 2005

Answers (1)

jfriend00
jfriend00

Reputation: 708116

Can I push data after async request without to wait for it? Something like res.update(blabla)?

No. You can't. If you are obtaining some of your data asynchronously, then you need to wait until you have actually obtained all the data before calling res.render().

So, imagine you wanted to get data from two external web sites to use in res.render() operation.

const rp = require('request-promise');

app.get((req, res) => {
    Promise.all([rp(someURL1), rp(someUrl2)]).then([r1, r2] => {
        // got all data now in r1 and r2
        res.render('index/asd', {r1, r2});
    }).catch(err => {
        console.log(err);
        res.sendStatus(500);
    });
});

There is no such thing as res.update() or any way to send more data on the same response object after you've done res.render(). Once res.render() is done and has sent its data, the http connection is finished and closed. You can't send more data on it.


It would be possible to call res.render() for a template that does not need your data and then after that web page is loaded in the browser, it could make an ajax call to fetch some other data from the server which could then be inserted into the page by the javascript in the web page.

It is not possible to send data to the previous response after you've sent the original response.

It is theoretically possible to use res.write() to send data on a connection, keep the connection open and then send more data later on that same connection using res.write() again, but that isn't going to render your page in the browser and then update it later - that's now how browsers work.

It is possible to send data to a web page using a webSocket or socket.io connection (if the web page creates such a connection after being loaded into the browser), but I don't see how that applies here.


I think you have two practical options here:

  1. Wait to call res.render() until you have all the data.
  2. Call res.render() on a template that does not need your data. Then have the web page call back to the server with an ajax call to retrieve data and when it gets that data, it can insert it into the page.

If, long after your web page has been rendered and displayed in the browser, you then want to push some updated data to the web page, you can use a webSocket or socket.io connection. Using that the server can then send updates to the web page as they occur on the server and some receiving Javascript in the web page would manually modify the current web page display based on the newly received data. You would typically send JSON data and let the Javascript in the web page turn it into HTML in the page.

The way this would work is as follows:

  1. Upon initial page request, server uses res.render() to render the initial page and that is sent to the browser.
  2. Browser receives the HTML page, displays the HTML and runs the Javsacript.
  3. Javascript in the page, makes a webSocket or socket.io connection back to the server.
  4. Server receives the webSocket or socket.io connection and hangs onto it.
  5. Sometime in the future, server has new data to send to the page and formulates a message (usually JSON) and sends that over the webSocket or socket.io connection.
  6. Javascript in the web page receives incoming message from the server, examines the content of the message and decides what to do with that data - perhaps inserting some new data into the currently displayed page using DOM manipulations in the browser.

Upvotes: 3

Related Questions