2

I am making a NodeJS app with Express and Socket.io. I am trying to send some data in the form of an object from the server to the client, and I want this to happen when the page has been loaded. Then, some HTML can be changed with the object that's been received. I'm pretty sure that this is possible with Socket.io. However, when using window.onload = function() {...}, nothing happens. window.onload isn't even called.

When I try this without using NodeJS (just using the HTML page), it works fine. window.onload is called and all goes well. So why isn't this working within NodeJS? I know that it waits for all images, etc. to load and was having a problem with that, but that's been mostly resolved now. The image is loading fine. (I still can't load it with background-image though, does this make a difference?)

Also, am I going the correct way about sending data from server to client? I'd much rather use Socket.io than learn something new like Angular or React.

Here's my code:

main.js (client)

window.onload = function() {
  console.log('window loaded');   // this shows when not in NodeJS app
  alert('window ready');          // neither does this
  socket.emit('pageReady');       // so this doesn't run
}

socket.on('pageInfo', function(response) {
  console.log('page info received');    //this doesn't run either
  document.getElementById("schoolName").innerHTML = response.school_name;
});

app.js (server)

io.on('pageReady', function() {
  io.emit('pageInfo', response);       // response is defined earlier
  console.log('page ready recieved');  // this doesn't show
});
William Jones
  • 809
  • 2
  • 11
  • 29

1 Answers1

2

Regarding window.onload not running when you're running the webserver sounds very strange; your implementations looks fine. Could it be, like you're onto, that you're never finishing loading some assets?

Regarding your implementation of socket.io:

You're emitting events to the socket through socket.emit() but you're listening on events sent to your server, rather than the connected socket.

Try putting your event binding with in server connection event, like this:

io.on("connection", (socket) => {

  socket.on('pageReady', function() {
    socket.emit('pageInfo', response);
    console.log('page ready recieved');
  });

}

Regarding using socket.io in this case

It sounds like a bit over the top to use socket.io in this case, where you essentially want to call a server (fetch()) and get a response with data to use. To that end I'd recommend using the fetch API and structuring your express app more like a REST api:

server:

var app = Express();

app.get('/data', (request, response) => {
   response.send("hello");
}

client:

fetch('/data')
  .then((data) => {
    console.log(data); // => hello
  });
Fredrik Schön
  • 4,888
  • 1
  • 21
  • 32
  • Thanks! This seems like a better way of doing things, so I've implemented it into my code. Unfortunately, my problem is still persisting. – William Jones Mar 16 '19 at 18:47
  • I read your question too fast and didn't realize you had issues even sending the event at all! Don't have a clear answer for that, sorry. – Fredrik Schön Mar 16 '19 at 18:50
  • Ah, ok. Thanks for the answer anyway. – William Jones Mar 16 '19 at 18:51
  • Hmm, only just noticed the edit. From what I can tell, I won't have to faff around with `window.onload` if I use this? – William Jones Mar 16 '19 at 19:00
  • It would essentially work in the same way, so you'd probably still want to listen to window.onload (so you don't try to change the DOM before it has loaded). Are you 100% sure that the client script is actually loaded on the client side with a script tag? – Fredrik Schön Mar 17 '19 at 15:47
  • Is there any way I can use `res.sendFile` and `res.send` together to send data? – William Jones Mar 17 '19 at 21:07
  • [I think so!](https://stackoverflow.com/questions/33027089/res-sendfile-in-node-express-with-passing-data-along) – Fredrik Schön Mar 18 '19 at 14:49