Piotr Stulinski
Piotr Stulinski

Reputation: 9471

durandal knockout - strange binding / timing error?

I am experiencing some strange binding / timing behavior - i have pasted the relevant code. When i step through the code slowly manually in chrome it populates my drop down correctly when i let it run normally it does not.... what am i doing wrong? I have put in the console output where the timing of my 'got provinces' is different.

 var provinces = ko.observableArray();

 var vm = {
        activate: activate,
        viewAttached:viewAttached,
        title: 'Home View',
        provinces: provinces,
    };

return vm;

  function activate() {
            getProvinces(provinces);
            return true;
    }

function viewAttached() {
    console.log("got data");
}  

The simple ajax call is as follows where i pass in my observable (this is taken almost exactly from the John Papa pluralsight demo):

getProvinces: function (observableArray) {
   observableArray([]);

   var options = {
        url: currentServer + 'regions/GetInUseProvinces',
        type: 'GET',
        async: true,
        dataType: "json",
    };

    $.ajax(options).then(querySucceded);

    function querySucceded(data) {
        var provinces = [];
        data.forEach(function(item) {
            var s = new MedappData.Data.Province(item.Name, item.ID);
            provinces.push(s);
        });
        observableArray(provinces);
        console.log('got provinces');
    }
},  

The console output differs as follows between the two.

When i put break points in and step through it manually i get the following and it works perfectly:

["Activating", Object]
["[viewmodels/shell] ", "Medapp loaded..."] system.js:62
["Activating Route", Object, Object, n.Object]
["Activating", Object]
["Binding", "views/shell", Object]
got provinces vendor:5319
["Binding", "views/nav", ko.bindingContext]
["Binding", "views/home", Object]
["Binding", "views/footer", ko.bindingContext]
got data

When i remove my break points and let it runs the output is as follow and nothing is populated.

["Activating", Object]
["[viewmodels/shell] ", "Medapp loaded..."] system.js:62
["Activating Route", Object, Object, n.Object]
["Activating", Object]
["Binding", "views/shell", Object]
["Binding", "views/nav", ko.bindingContext]
["Binding", "views/home", Object]
["Binding", "views/footer", ko.bindingContext]
got provinces vendor:5319
got data 

Upvotes: 1

Views: 729

Answers (1)

RainerAtSpirit
RainerAtSpirit

Reputation: 3723

getProvinces is a async operation, so you have to return a promise in order to allow Durandal to figure out when it's allowed to continue composing. Returning true after an async operation doesn't do that.

$.ajax(... already returns a promise, so changing getProvinces to

return $.ajax(options).then(querySucceded);

and in activate

function activate() {
    return getProvinces(provinces);
}

should do the trick.

Upvotes: 3

Related Questions