im building a simple chat app with socket io angular 2(typescript) and nodejs as a backend server i have this function which works perfectly when i click the connect button
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;
})
}
however i try to use bootbox.prompt whenever the user tries to connect so i wrap all the code inside this simple function
addUser(){
bootbox.prompt('what is your name ',function(name){
connectUser(name); // this is the function in the first code snippet
});
}
i get this wierd error Cannot read property 'emit' of undefined how can i fix that and what is the problem here ?
When you are calling connectUser from addUser you are doing it from another function (apparently a callback).
Javascript binds 'this' to that wrapper function you are using, and that function doesn't have a 'socket' member.
When you call the function connectUser from the connect button directly, you are probably calling it inline from the object, thus, 'this' is bound to the object that does contain the 'socket' member.
Review the following snippet to have a look on how the "function() { }" wrapper is affecting you:
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();
Basically you can probably just change this:
function(name) { connectUser(name); }
For this
(name) => connectUser(name)
and it should work.