javascriptnode.jssocket.ioejsc9.io

I can't get live data through socket.io to client and display it on the page


I have an application that should live update some data from a websocket API. This data is shown when I console.log it on the server side. I tried storing it in a variable and pass it through the emit function of Socket.io. But it gives a null as a result when I try to get the data to display on the front-end.

What am I doing wrong that it won't show on page?

Server side code:

 app.get("/", function(req, res){
    res.render("home");
});

app.get("/fat-finger", function(req, res){
    binance.prices((error, ticker) => {
        var prijzen = ticker;
        res.render("fat-finger", {laatstePrijzen: prijzen});
    });
});

app.set('port', process.env.PORT || 3000);
var server = http.createServer(app);
var io = require('socket.io').listen(server);
server.listen(app.get('port'));
console.log("Server is up and running!")

io.on('connection', function(client) {
    console.log('Client connected...');
    var coinData;

    binance.websockets.prevDay('BTCUSDT', (error, response) => {
        coinData = response;
        console.log(coinData);
    });

    io.emit('coins', coinData);  //this code sending data from server to client
});

Front-End Code (Client):

<% include partials/header %>

<header class="ui main container">
        <h1>Fat Finger Scanner</h1>
    </header>
    <main class="ui text container">
        <section class="ui container segment">
            <h4>You can find Fat Fingers quickly with this tool!</h4>
            <div id="coindatadiv">
                <script>
                    var div = document.getElementById("coindatadiv");
                    socket.on("connect", function(allCoinData){
                        div.innerHTML += "<p>"+allCoinData+"</p>";
                    });
                </script>
            </div
        </section>
    </main>
</div>

<% include partials/footer %>

The socket connection is made properly, so that should not be the problem on either sides of the setup. The only thing I get stuck at is passing through the data from the server to the client side and be able to show the data update itself live on the page.


Solution

  • Looks like you're receiving the data wrong on the client-side. On the server side, you're calling io.emit('coins', coinData); to send coin data to the client. You're naming the event "coins" so on the client side, you have to listen for the "coins" event instead of the "connect" event.

    var div = document.getElementById("coindatadiv");
    socket.on("coins", function(allCoinData){
        div.innerHTML += "<p>"+allCoinData+"</p>";
    });
    

    Hope this makes sense, let me know if anything else comes up! :)

    I now realize that you're using an API and want to keep all clients up to date with the latest information from that API. What you might want to do instead is just emit to all sockets whenever the API updates:

    Change

    io.on('connection', function(client) {
        console.log('Client connected...');
        var coinData;
    
        binance.websockets.prevDay('BTCUSDT', (error, response) => {
            coinData = response;
            console.log(coinData);
        });
    
        io.emit('coins', coinData);  //this code sending data from server to client
    });
    

    To

    var coinData = 'not yet defined';
    
    binance.websockets.prevDay('BTCUSDT', (error, response) => {
        coinData = response;
        io.emit('coins', coinData);
        console.log(coinData);
    });
    
    io.on('connection', function(client) {
        client.emit('coins', coinData); 
    });
    

    This will emit to all sockets each time you get a message from your API.