Rohan Büchner
Rohan Büchner

Reputation: 5393

KO Single page app. Async data calls randomly failing/not binding

I've got a single screen with multiple dropdowns. Each get populated via a web api call. I'm in an active directory environment. I'm using the Durandal SPA framework.

enter image description here

At the moment I do the loading of my dropdowns on the activate of my view. EG.

  activate: function (data) {
            var id = data.id || undefined;
            userRole(data.mode || 'usr');

            // i added this as i was thinking i dont need to initialize the "static" dropdowns every time
            // I'm testing my code without this as we speak.
            if (!hasBeenInit) {
                lookupInit(id);
                hasBeenInit = true;
            }
        },
   }

[A] It seems like randomly, depending on the amount of server load (I'm guessing) my dropdowns wont get populated..

[B] Some of the dropdowns are dependant on the value of another. I've I've achieved this by making use of the knockout subscribe event. and updating my observable collections.

Javascript

userInfo.BuildingCode.subscribe(function (value) {
        vm.userInfo.FloorCode(undefined);
        http.get('api/Floor', { id: value }, false)
            .done(function (response) {
                console.log('api/Floor');
                vm.lookups.allFloors(response);
                console.log(vm.lookups.allFloors());
            });
    });

html

<select data-bind="options: lookups.allFloors, optionsText: 'FloorName', optionsValue: 'FloorCode', value: $root.userInfo.FloorCode"></select>

If I had to select the building value for example, the floor dropdown must get new values. The API call does happens, it seems like the observable array gets updated, but the values don't seem to be reflecting on the view.

Chrome console log

api/Floor main-built.js:14
[Object, Object, Object]

api/Floor main-built.js:14
[Object, Object, Object]

api/Floor main-built.js:14
[Object, Object, Object, Object, Object]

What can i do to ensure my lookups/dropdowns get populated each and every call. As well as their execution order stays as specified.

I've tried something like this, but it just feels wrong. I've also added an async false overload to the durandal http helper, but it didnt seem to work... any ideas? :\

   http.get('api/employmenttype')
            .done(function (response) {
                console.log('api/employmenttype');
                vm.lookups.allEmploymentTypes(response);
            })
            .then(function () {
                http.get('api/actionlist')
                    .done(function (response) {
                        console.log('api/actionlist');
                        vm.lookups.allActionListOptions(response);
                    })
                    .then(function () {  ... } );

UPDATE

I investigated my async call overload. Ended up being the culprit, once i fixed it, my data seemed to load constantly. The only side effect is that none of my server side data sets loads asynchronously. (Which i'm hoping I wont get crucified for).

Upvotes: 0

Views: 305

Answers (1)

RainerAtSpirit
RainerAtSpirit

Reputation: 3723

Assuming that lookupInit is a async call make sure to return the promise. So activate becomes something along the line.

activate: function (data) {
    var id = data.id || undefined;
    userRole(data.mode || 'usr');

    // i added this as i was thinking i dont need to initialize the "static" dropdowns every time
    // I'm testing my code without this as we speak.
    if (!hasBeenInit) {
        hasBeenInit = true;
        return lookupInit(id);
    }
    return true;
},

I'm still digesting the other part(s) of the question, but thought that might get you started already.

Update: The value of vm.userInfo.FloorCode is reset to undefined, but in the select there's no optionsCaption: 'Please select...' defined. It might be that ko won't update the option values because is can't find a corresponded value.

Upvotes: 1

Related Questions