无法读取未定义的打字稿属性'emit'

时间:2017-04-26 21:40:47

标签: angular typescript socket.io

我正在使用socket io angular 2(typescript)和nodejs作为后端服务器构建一个简单的聊天应用程序 我有这个功能,当我点击连接按钮

时,它可以正常工作

connectUser(name){
  
  	 
  	if (name == null || name == ""){
  	return 	console.log('you must enter a valid username');
  	
  	}
  	this.username = name;

  	this.socket.emit('add-user',name);
  	//load connected users in the user-window section
  	this.socket.emit('request-users',{data:'request users success'});
  	var connecctedUsersListener$ = Observable.fromEvent(this.socket,'users');
  	connecctedUsersListener$.subscribe((observer:any)=>{
  		this.users = observer;
 	},(err)=>{
  		if(err) throw err;
  	},()=>{
  		console.log('complet');
  	});
  
  //load messages and keep track of Them 
  this.socket.emit('request-messages',{data:'request Messages success'});
  var messageListener$ = Observable.fromEvent(this.socket,'message');
  messageListener$.subscribe((observer:any) =>{
  	this.messages = observer;
  	
  })

  }

然而,每当用户尝试连接时我尝试使用bootbox.prompt,所以我将所有代码包装在这个简单的函数中

addUser(){
  bootbox.prompt('what is your name ',function(name){
  connectUser(name); // this is the function in the first code snippet 	

  	  });
  }

我得到了这个奇怪的错误无法读取未定义的属性'emit' 我该如何解决这个问题?这里有什么问题?

1 个答案:

答案 0 :(得分:3)

当您从addUser调用connectUser时,您正在从另一个函数(显然是回调)中执行此操作。

Javascript将“ this ”绑定到您正在使用的包装器函数,并且该函数没有“ socket ”成员。

当您直接从连接按钮调用函数 connectUser 时,您可能正在从对象内联调用它,因此,' this '绑定到对象上确实包含' socket '成员。

查看以下代码段,了解“function(){}”包装器对您的影响:

class Whatever {
   socket: { emit: string }

   constructor()
   {
      this.socket = { emit: 'works' };
   }

   doSomething()
   {
      console.warn(this.socket.emit);
   }

   works()
   {
      this.doSomething();
      (() => this.doSomething())();
   }

   doesntWork()
   {
      (function () { this.doSomething() })();
   }
}

let obj = new Whatever();
obj.works();
obj.doesntWork();

基本上你可以改变这个:

function(name) { connectUser(name); }

对于此

(name) => connectUser(name) 

它应该有用。