3

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;
})();
2
  • You need to show where the error is occurring. Commented Apr 4, 2013 at 2:56
  • In the Done method callback (I put some comments there) Commented Apr 4, 2013 at 2:59

1 Answer 1

2

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

3 Comments

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.
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); }
Can you please explain a bit exactly what does that do "this.portalVM" in the function call.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.