最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - TypeError: Cannot read property 'emit' of undefined - Stack Overflow

programmeradmin3浏览0评论

The problem is that Whenever I try to fire "this.io.emit" event a TypeError occurs. It gives only while I write this statement "this.io.emit" inside "socket.on" block otherwise, if I write it outside this block it generates no error.

This is the main server.js file to call the other libraries:

const express = require('express'),
http = require('http'),
socketio = require('socket.io');

class App{

constructor()
{
    this.port =  process.env.PORT || 81;
    this.host = `localhost`;        
    this.app = express();
    this.http = http.Server(this.app);
    this.socket = socketio(this.http);
}
appConfig(){
    new config(this.app);
}
appRoutes(){
    new routes(this.app,this.socket).routesDefault();
}
appDefault(){
    this.appConfig();
    this.appRoutes();
    this.http.listen(this.port,this.host,()=> {
        console.log(`Listening`);
    });
}}

my server side code is:

'use strict';
class Routes {

constructor(app,socket) {
    this.app = app;
    this.io = socket;
    this.users=[];
}

routesTemplate()
{
    this.app.get('/',function(req,res){
        res.render('index');
    });
}

socketEvents()
{
    this.io.on('connection',(socket) => {
        socket.on('send message',function(data)
        {
            this.io.emit('new message',data);//here the error lies.
        });
    }); 
}
routesDefault()
{
    this.routesTemplate();
    this.socketEvents();
}}  
module.exports = Routes;

I also tried to access "this.users.The length" inside socket.on the statement and it generated the same TypeError: cannot read property length. I have no idea why it is occurring. Please help me to resolve this problem.

Client Side:

        <script>
        $(function($){
            var socket = io.connect();
            var $messageForm = $('#send-message');
            var $messageBox = $('#message');
            var $chat = $('#chat');

            $messageForm.submit(function(e){
                e.preventDefault();
                socket.emit('send message',$messageBox.val());
                $messageBox.val("");
            });
            socket.on('new message',function(data){
                $chat.append(data+ "<br/>");
            });
        });
    </script>

The problem is that Whenever I try to fire "this.io.emit" event a TypeError occurs. It gives only while I write this statement "this.io.emit" inside "socket.on" block otherwise, if I write it outside this block it generates no error.

This is the main server.js file to call the other libraries:

const express = require('express'),
http = require('http'),
socketio = require('socket.io');

class App{

constructor()
{
    this.port =  process.env.PORT || 81;
    this.host = `localhost`;        
    this.app = express();
    this.http = http.Server(this.app);
    this.socket = socketio(this.http);
}
appConfig(){
    new config(this.app);
}
appRoutes(){
    new routes(this.app,this.socket).routesDefault();
}
appDefault(){
    this.appConfig();
    this.appRoutes();
    this.http.listen(this.port,this.host,()=> {
        console.log(`Listening`);
    });
}}

my server side code is:

'use strict';
class Routes {

constructor(app,socket) {
    this.app = app;
    this.io = socket;
    this.users=[];
}

routesTemplate()
{
    this.app.get('/',function(req,res){
        res.render('index');
    });
}

socketEvents()
{
    this.io.on('connection',(socket) => {
        socket.on('send message',function(data)
        {
            this.io.emit('new message',data);//here the error lies.
        });
    }); 
}
routesDefault()
{
    this.routesTemplate();
    this.socketEvents();
}}  
module.exports = Routes;

I also tried to access "this.users.The length" inside socket.on the statement and it generated the same TypeError: cannot read property length. I have no idea why it is occurring. Please help me to resolve this problem.

Client Side:

        <script>
        $(function($){
            var socket = io.connect();
            var $messageForm = $('#send-message');
            var $messageBox = $('#message');
            var $chat = $('#chat');

            $messageForm.submit(function(e){
                e.preventDefault();
                socket.emit('send message',$messageBox.val());
                $messageBox.val("");
            });
            socket.on('new message',function(data){
                $chat.append(data+ "<br/>");
            });
        });
    </script>
Share Improve this question asked Feb 2, 2017 at 19:32 sagarsagar 7321 gold badge7 silver badges25 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 7

The context of this is an issue in your code. To pass the current context use bind or the Arrow Function. In javascript, the value of this is defined by how you called the function, which in your case is socket object.

socketEvents()
{
    this.io.on('connection',(socket) => {
        socket.on('send message',function(data)
        {
            this.io.emit('new message',data);//here the error lies.
        }bind(this));
    }); 
}

P.S.: Edited, now this code works fine. I would like to suggest the below post described about it.

What are the differences (if any) between ES6 arrow functions and functions bound with Function.prototype.bind?

This is because the context of this is different for the inner function.

Try:

socketEvents()
{
    this.io.on('connection',(socket) => {
        socket.on('send message',function(data)
        {
            socket.emit('new message',data);//here the error lies.
        });
    }); 
}

use io.emit() instead of socket.broadcast.emit()

io.on('connection', function(socket){
  socket.broadcast.emit('request', /* */); 
  io.emit('broadcast', /* */); 
  socket.on('reply', function(){ /* */ }); 
});
发布评论

评论列表(0)

  1. 暂无评论