0

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);
            });
          });
Community
  • 1
  • 1
Richard
  • 8,193
  • 28
  • 107
  • 228

2 Answers2

2

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);
    });
    
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thank you, I will give it a try – Richard Oct 04 '16 at 13:24
  • Thanks Bergi, that worked, it now calls that function. However, I am now having an issue that something in that function doesn't work. Would you mind looking at the following please? http://stackoverflow.com/questions/39854896/typscript-not-inserting-into-mongo-collection – Richard Oct 04 '16 at 15:34
1

There are a few things wrong here.

In ES6 (and thus TypeScript), you need to refer to instance members using explicit this, such as this.setLocalMessage. Just writing setLocalMessage is invalid no matter where the code is.

Inside a function, the this object will probably not be what you expect anyway. You need to capture the this object from outside the function and put it in a variable, like so:

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

Alternatively, you can use an arrow expression, in which this is the same as what it is in the code around it:

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(message => this.setLocalMessage(message));
        });
    });
});

It's not an issue of TypeScript itself. Without it, the code will just fail at runtime.

GregRos
  • 8,667
  • 3
  • 37
  • 63
  • Thank you, I will give it a try – Richard Oct 04 '16 at 13:26
  • Thanks Greg, that worked, it now calls that function. However, I am now having an issue that something in that function doesn't work. Would you mind looking at the following please? http://stackoverflow.com/questions/39854896/typscript-not-inserting-into-mongo-collection – Richard Oct 04 '16 at 15:34