1

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);
            });
          });
3
  • 1
    It might be a typo, but your function is declared setLocalMessage and your error says setLocalNessage - is this a typo or the actual problem? Commented Oct 4, 2016 at 13:09
  • It might also be worth adding the "typescript" tag (maybe even instead of the "javascript" tag), as this is typescript code. Commented Oct 4, 2016 at 13:11
  • Sorry, was a typo, fixed now Commented Oct 4, 2016 at 13:11

2 Answers 2

3

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);
    });
    
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, I will give it a try
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? stackoverflow.com/questions/39854896/…
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.

2 Comments

Thank you, I will give it a try
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? stackoverflow.com/questions/39854896/…

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.