简体   繁体   中英

Getting missing error handler socket message, cannot read property 'timerID' of undefined using Node.js and Socket.io

am getting the following error which run the server using Node.js and socket.io.

error

C:\Users\황진우\Desktop\nodejstest>node app2
Server Running at http://127.0.0.1:52273
Missing error handler on `socket`.
TypeError: Cannot read property 'timerID' of undefined
    at Socket.<anonymous> (C:\Users\황진우\Desktop\nodejstest\app2.js:97:27)
    at emitOne (events.js:77:13)
    at Socket.emit (events.js:169:7)
    at Socket.onevent (C:\Users\황진우\Desktop\nodejstest\node_modules\socket.io\lib\socket.js:335:8)
    at Socket.onpacket (C:\Users\황진우\Desktop\nodejstest\node_modules\socket.io\lib\socket.js:295:12)
    at Client.ondecoded (C:\Users\황진우\Desktop\nodejstest\node_modules\socket.io\lib\client.js:193:14)
    at Decoder.Emitter.emit (C:\Users\황진우\Desktop\nodejstest\node_modules\socket.io\node_modules\socket.io-parser\node_modules\component-emitter\index.js:134:20)
    at Decoder.add (C:\Users\황진우\Desktop\nodejstest\node_modules\socket.io\node_modules\socket.io-parser\index.js:247:12)
    at Client.ondata (C:\Users\황진우\Desktop\nodejstest\node_modules\socket.io\lib\client.js:175:18)
    at emitOne (events.js:77:13)

code is given below.

server side app2.js

var fs = require('fs');
var ejs = require('ejs');
var http = require('http');
var express = require('express');


var counter = 0;
function Product(name, image, price, count){
    this.index = counter++;
    this.name = name; 
    this.image = image;
    this.price = price;
    this.count = count;
};

var products = [
    new Product('JavaScript','chrome.png', 28000 , 30 ),
    new Product('jQuery','chrome.png',28000 , 30),
    new Product('Node.js','chrome.png', 32000, 30),
    new Product('Socket.io','chrome.png', 17000, 30),
    new Product('Connect','chrome.png', 18000, 30),
    new Product('Express','chrome.png', 31000, 30),
    new Product('EJS','chrome.png', 12000, 30)
];


var app = express();
var server = http.createServer(app);


app.use(express.static(__dirname+'/public'));


app.route('/').get(function(req,res){

    var HTMLPage = fs.readFileSync('HTMLPage2.html','utf-8');


    res.send(ejs.render(HTMLPage,{
        products : products
    }));
});


server.listen(52273, function(){
    console.log('Server Running at http://127.0.0.1:52273');
});


var io = require('socket.io').listen(server);
io.sockets.on('connection', function(socket){

    function onReturn(index){

        products[index].count++;


        clearTimeout(cart[index].timerID);


        delete cart[index];


        io.sockets.emit('count', {
            index : index,
            count : products[index].count
        });
    };


    var cart = {};


    socket.on('cart',function(index){

        products[index].count--;


        cart[index] = {};
        cart[index].index = index;
        cart[index].timerID = setTimeout(function(){
            onReturn(index);
        }, 1000*5);


        io.sockets.emit('count',{
            index : index,
            count : products[index].count
        });
    });





    socket.on('buy', function(index){

        clearTimeout(cart[index].timerID);


        delete cart[index];


        io.sockets.emit('count', {
            index: index,
            count: products[index].count
        });
    });


    socket.on('return', function(index){
        onReturn(index);
    });
});

Client side HTMLPage2.HTML

<!DOCTYPE html>
<html>
    <head>

        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.css" />
        <script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js"></script>
        <script src="/socket.io/socket.io.js"></script>
        <script>
            $(document).ready(function() {

                function changeIcon(parent, from, to){
                    var target = $('.ui-btn-text', parent).next();
                    target.removeClass(from).addClass(to);
                }

                function changeCount(index, count){
                    $('li[data-index = '+index + '] .ul-li-count').html(count);
                }

                var socket = io.connect();


                socket.on('count', function(data){

                    changeCount(data.index, data.count);
                });

                $('.product > a[data-icon]').click(function(){
                    if($(this).attr('toggle') != 'off'){

                        var index = $(this).attr('data-index');


                        socket.emit('cart', Number(index));


                        changeIcon(this, 'ui-icon-check', 'ui-icon-back');


                        $(this).attr('toggle', 'off');

                    }else{

                        var index = $(this).attr('data-index');

                        if(confirm('물건을 구매하겠습니까?')){

                            socket.emit('buy',Number(index));


                            $(this).parent().remove();
                            $('#listview').listview('refresh');
                        }else{

                            socket.emit('return',Number(index));


                            changeIcon(this, 'ui-icon-back','ui-icon-check');
                        }

                        $(this).attr('toggle','on');
                    }
                });

            });
        </script>
    </head>
    <body>
        <div data-role = "page">
            <div data-role = "header">
                <h1>Store</h1>
            </div>
            <div data-role="content">
                <ul id="listview" data-role="listview" data-insert="true" data-filter="true">
                <li data-role="list-divider">products</li>
                <% products.forEach(function (item, index) { %>
                <li class="product" data-index="<% item.index %>">
                    <a href="#">
                        <img src="chrome.png" />
                        <h3><%= item.name %></h3>
                        <p><%= item.price %>원</p>
                        <span class="ul-li-count"><%= item.count %></span>
                    </a>
                    <a href="#" data-icon="check" data-index="<%= item.index %>"></a>
                </li>
                <% }); %>
                </ul>
            </div>
            </div>          
    </body>

</html>

I am getting error at this line. 'clearTimeout(cart[index].timerID);'

Please help me to resolve this error.

This error is triggered when users want to directly buy items without putting them on cart. In that case, the cart event will never be fired, thus cart[index] will never exist.

socket.on('buy', function(index){

    if(cart[index]){

        clearTimeout(cart[index].timerID);


        delete cart[index];
    }

    io.sockets.emit('count', {
        index: index,
        count: products[index].count
    });
});

Also, you should handle the error event like this:

socket.on('error',function(er){
    console.log(er);
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM