Search code examples
ajaxknockout.jsgetjson

KnockoutJS default value not set when getJSON


I change from AngularJS to KnockoutJS. With the least piece I have a problem I spent now two days for already.

<div class="form-group">
    <label for="account">Konto:</label>
    <select class="form-control" data-bind="options: accounts, value: account</select>
</div>

This is account:

self.account = ko.observable('Bargeldkonto');

This works great when I define this I realized later. Second option is selected in my case:

self.accountstest = ko.observable([]);    
self.accountstest = ko.observable(['Avadis','Bargeldkonto','Bitcoin','Lohnkonto','Mietkaution','Sparen 3','Sparen 3 Kto. 2','Sparkonto Liam Noa','Sparkonto SQ','Trading SQ']);

But this way, it doesn't work. Always first is selected:

        self.accounts = ko.observableArray([]);
        $.getJSON("entry_account_mysql.php", function(data) {
            self.accounts(data);
            //alert(JSON.stringify(data));
            console.log("accounts: " + self.accounts());
        });

I know it has to do with timing, but don't know have to behave with it in KnockoutJS. Some say $getJson is not good. Funny, $.ajax works, but I receive now this error in console: "Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user’s experience.":

        self.accounts = ko.observableArray([]);
        $.ajax({
            url: "entry_account_mysql.php",
            async: false,
            success: function(data) {
                self.accounts(data);
            }
        });

Back to $.getJSON? But how?


Solution

  • Wrap your select in a virtual element binding if:

    <!-- ko if: accounts.length -->
      <select class="form-control" data-bind="options: accounts, value: account"></select>
    <--! /ko -->
    

    This makes sure the element gets rendered only if accounts holds any elements, and by this, should solve your timing issues.