Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am trying to use typescript, Knockout and azure mobile services to get some data. The problem is when I get data from azure, it's async and I can not get the viewmodel object any more. I think it's some scope/closure issue, please help me find the solution. It is null in the call back function for Done();

Here is my TypeScript code:

class pmViewModel {
    public welcomeMsg: string;
    public totalCount: number;
    constructor () {
        this.welcomeMsg = "";
    }
}

class Manager {
    client: any;
    portalVM: pmViewModel;
    constructor () {
        this.client = new WindowsAzure.MobileServiceClient("url", "key");
        this.portalVM = new pmViewModel();
    }

    LoadData() {
        console.log("load data for management portal");
        this.portalVM.welcomeMsg = "Hello";
        this.portalVM.totalCount = 0;
        var dataTable = this.client.getTable('dataTable');

        dataTable.take(1).includeTotalCount().read().done(this.populateTotal,this.portalVM);

        ko.applyBindings(this.portalVM);
        };

        populateTotal(result, vm) {
            console.log(result);
            console.log(vm); //null here
            this.portalVM.totalCount = 100000;////this is also null
        }
}

and generated JavaScript code:

var pmViewModel = (function () {
    function pmViewModel() {
        this.welcomeMsg = "";
    }
    return pmViewModel;
})();
var Manager = (function () {
    function Manager() {
        this.client = new WindowsAzure.MobileServiceClient("url", "key");
        this.portalVM = new pmViewModel();
    }
    Manager.prototype.LoadData = function () {
        console.log("load data for management portal");
        this.portalVM.welcomeMsg = "Hello";
        this.portalVM.totalCount = 0;
        var dataTable = this.client.getTable('dataTable');
        dataTable.take(1).includeTotalCount().read().done(this.populateTotal, this.portalVM);
        ko.applyBindings(this.portalVM);
    };
    Manager.prototype.populateTotal = function (result, vm) {
        console.log(result);
        console.log(vm);
        this.portalVM.totalCount = 100000;
    };
    return Manager;
})();
share|improve this question
    
You need to show where the error is occurring. –  RobG Apr 4 '13 at 2:56
    
In the Done method callback (I put some comments there) –  AD.Net Apr 4 '13 at 2:59

1 Answer 1

up vote 2 down vote accepted

Relevant line here:

dataTable.take(1).includeTotalCount().read().done(this.populateTotal,this.portalVM);

You need to capture the 'this' binding of populateTotal since it's going to be invoked as a callback without context.

Option 1:

[etc...].done((result, vm) => this.populateTotal(result, vm), this.portalVM);

Option 2:

[etc...].done(this.populateTotal.bind(this), this.portalVM);
share|improve this answer
    
Your solution looks correct, but all functions have their own context. The issues is that the this value of LoadData isn't set to the object that the OP expects. The value of this is set by the call, which is what you've done. –  RobG Apr 4 '13 at 4:56
    
Thanks, I'll try it tonight –  AD.Net Apr 4 '13 at 17:10
    
Thanks, it worked. I made slight modification. done((result) => this.populateTotal(result), this.portalVm) populateTotal(result) { this.portalVm.totalCount = result.totalCount; ko.applyBindings(this.portalVm); } –  AD.Net Apr 4 '13 at 23:03
    
Can you please explain a bit exactly what does that do "this.portalVM" in the function call. –  AD.Net Apr 4 '13 at 23:04

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.