Greg Gum
Greg Gum

Reputation: 38109

`this` in callback points to wrong object

I have this viewModel:

import app = require("durandal/app");
import appViewModel = require("appViewModel");
import dataService = require("dataService");

class Home{
    section = ko.observable<string>();
    activeScreen = ko.observable<string>("nativeLanguage/selectNativeLanguage");

constructor() {
    app.on('home:activateView').then(this.activateView);
}

activateView(view) {
    this.activeScreen(view);
}

activate() {
    return this.getSection();
}

getSection() {
    return dataService.getSection('HOME_PAGE').then((data) => {
        this.section(data.results[0]);
    });
}
}
export = Home;

This compiles without error.

However, when it runs, and activateView is called as a callback, this is pointing to app not to Home so the activeScreen property is undefined.

How do I resolve this?

Upvotes: 1

Views: 331

Answers (3)

Radim K&#246;hler
Radim K&#246;hler

Reputation: 123901

While you have your answer, the way I prefer is a bit different:

convert function/method definition - into "property referencing function"

// instead of class method
// public activateView(view) {

// use the "property"
public activateView = (view) => {
    this.activeScreen(view);
}

That will reduce the need to pass explicit params like this

.then((view) => this.activateView(view))

because this will work again:

.then(this.activateView)

Upvotes: 2

Martin
Martin

Reputation: 16300

You could also do then(this.activateView.bind(this))

Upvotes: 1

basarat
basarat

Reputation: 276255

Since you are passing the function to someone else to call in .then(this.activateView); you need to preserve the context yourself, best if you do : .then((view)=>this.activateView(view));

More about this : https://www.youtube.com/watch?v=tvocUcbCupA

Upvotes: 2

Related Questions