Richard Richard - 2 months ago 6
TypeScript Question

Javascript/Typescript 'this' scope

I am working with Ionic2 and Meteor. I do however have a Javascript/Typescript issue relating to the scope of the

this
object.

I have read that I should use
bind
when I don't have handle on
this
at the appropriate level.

I probably don't understand the concept, because I try the following, but get an error trying to call a function.

this.subscribe('messages', this.activeChat._id, this.senderId, () => {
this.autorun(() => {
let promiseMessages: Promise<Mongo.Collection<Message>> = this.findMessages();
promiseMessages.then((messageData: Mongo.Collection<Message>) => {
messageData.find().forEach(function (message: Message) {
setLocalMessage.bind(message);
});
});
});


and

private setLocalMessage(message: Message): void {
this.localMessageCollection.insert(message);
}


I get the following error when I try build the app:


ERROR in ./app/pages/messages/messages.ts
(72,19): error TS2304: Cannot find name 'setLocalMessage'.



UPDATE

Thank you for the advise below.

I am now using the following, and it works.

let promiseMessages: Promise<Mongo.Collection<Message>> = this.findMessages();
promiseMessages.then((messageData: Mongo.Collection<Message>) => {
messageData.find().forEach((message: Message) => {
this.setLocalMessage(message);
});
});

Answer

I have read that I should use bind when I don't have handle on this at the appropriate level.

That's a bit outdated now, better have a look at How to access the correct `this` / context inside a callback? these days which also shows you how to use arrow functions.

You're getting the error message because setLocalMessage is not a variable but still a property of this so you have to access it as such. There are basically three solutions in your case:

  • bind

    messageData.find().forEach(this.setLocalMessage.bind(this));
    
  • the context argument of forEach (assuming it's the Array method):

    messageData.find().forEach(this.setLocalMessage, this);
    
  • another arrow function:

    messageData.find().forEach((message: Message) => {
        this.setLocalMessage(message);
    });
    
Comments