Unable to process binding, country is not defined
<p>I am trying to bind a <code>&lt;select&gt;</code> to a ko.observableArray and I am getting this error:</p>

<blockquote>
  <p>Uncaught ReferenceError: Unable to process binding "options: function
  (){return _countries }" Message: country is not defined</p>
</blockquote>

<p>Here is my code.</p>

<p>HTML:</p>

<pre><code>&lt;!-- This is the home page --&gt;

&lt;html&gt;

&lt;head&gt;
    &lt;title&gt;The Vegan Repository&lt;/title&gt;
    &lt;meta charset="utf-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;
    &lt;!-- Load libraries --&gt;



    &lt;!-- System.js --&gt;
    &lt;script 
        src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.18.4/system-csp-production.js"&gt;
    &lt;/script&gt;

    &lt;!-- JQuery --&gt;
    &lt;script 
        src="bower_components/jquery/dist/jquery.min.js"&gt;
    &lt;/script&gt;

    &lt;!-- Bootstrap CSS --&gt;
    &lt;link 
        rel="stylesheet" 
        href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" 
        integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7"
        crossorigin="anonymous"&gt;

    &lt;!-- Bootstrap JS --&gt;
    &lt;script 
        src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" 
        integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS"
        crossorigin="anonymous"&gt;
    &lt;/script&gt;

    &lt;!-- Knockout JS --&gt;
    &lt;script 
        src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"&gt;
    &lt;/script&gt;

    &lt;!-- Styles --&gt;
    &lt;link rel="stylesheet" type="text/css" href="styles/image.css"&gt;
    &lt;link rel="stylesheet" type="text/css" href="styles/text.css"&gt;
    &lt;link rel="stylesheet" type="text/css" href="styles/header.css"&gt;
    &lt;link rel="stylesheet" type="text/css" href="styles/form.css"&gt;
    &lt;link rel="stylesheet" type="text/css" href="styles/select.css"&gt;

    &lt;!-- Google Maps API --&gt;
    &lt;!-- &lt;script src="http://maps.googleapis.com/maps/api/js"&gt;&lt;/script&gt;
    &lt;script src="scripts/map.js"&gt;&lt;/script&gt; --&gt;
    &lt;script src="scripts/scroll_to_anchor.js"&gt;&lt;/script&gt;
    &lt;script src="scripts/xml2json.min.js"&gt;&lt;/script&gt;
    &lt;script src="scripts/country.js"&gt;&lt;/script&gt;

&lt;/head&gt;
&lt;body &gt;
    &lt;div style="margin-bottom: 100px;" class="full_size dimmed"&gt;
        &lt;div style="position:fixed; z-index: -1;"&gt;
        &lt;video 
            style="position:fixed;" 
            autoplay loop muted
            poster="assets/images/home_page/polina.jpg" 
            id="bgvid"&gt;
            &lt;!--&lt;source src="polina.webm" type="video/webm"&gt;--&gt;
            &lt;source src="assets/videos/polina.mp4" type="video/mp4"&gt;
        &lt;/video&gt;
        &lt;/div&gt;

        &lt;div class="header dim"&gt;
            &lt;a href="http://www.w3schools.com" &gt;&lt;h5 id="app-name" class="nav-item clickable white-text medium-text left-text"&gt;THE VEGAN REPOSITORY&lt;/h5&gt;&lt;/a&gt;
            &lt;a href="http://www.w3schools.com" &gt;&lt;h5 (click)="clicked()" id="sign-in-button" class="nav-item clickable brand-colour-text medium-text right-text with-border"&gt;SIGN UP FREE&lt;/h5&gt;&lt;/a&gt;
            &lt;a href="http://www.w3schools.com" &gt;&lt;h5 class="nav-item clickable white-text medium-text right-text"&gt;LOGIN&lt;/h5&gt;&lt;/a&gt;
            &lt;a href="#home_page_footer" &gt;&lt;h5 class="nav-item clickable white-text medium-text right-text" &gt;BLOG&lt;/h5&gt;&lt;/a&gt;
            &lt;a href="#home_page_footer" &gt;&lt;h5 class="nav-item clickable white-text medium-text right-text" &gt;ABOUT&lt;/h5&gt;&lt;/a&gt;

        &lt;/div&gt;

        &lt;div id="motto-text" class="vertical-center"&gt;
            &lt;h5 class="white-text medium-text"&gt;THE VEGAN REPOSITORY&lt;/h5&gt;
            &lt;h1 id="main-text" class=" text-center white-text light-text extra-large-text"&gt;FIND VEGAN PRODUCTS NEAR YOU&lt;/h1&gt;
            &lt;a id="try-now-button" class="with-border clickable" href="#find-vegan-products-page" &gt;&lt;h5  class=" text-center medium-text"&gt;TRY NOW&lt;/h5&gt;&lt;/a&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;!--[if lt IE 9]&gt;
    &lt;script&gt;
        document.createElement('video');
    &lt;/script&gt;
    &lt;![endif]--&gt;

    &lt;?php
        $host = 'localhost';
        $port = 8889;
        $servername = "$host:$port";
        $username = "root";
        $password = "root";
        $db = "myDB";

        // Create connection
        $conn = new mysqli($servername, $username, $password, $db);
        // Check connection
        if ($conn-&gt;connect_error) {
            die("Connection failed: " . $conn-&gt;connect_error);
        } 

        // Create database
        /*$sql = "CREATE DATABASE myDB";*/

        // Create table
        /*$sql = "CREATE TABLE Persons
                (   PersonID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
                    LastName varchar(255),
                    FirstName varchar(255),
                    Address varchar(255),
                    City varchar(255)
                );";*/

        // Insert row into table
        $sql = "INSERT INTO Persons (Firstname, Lastname, Address, City)
                VALUES  ('John', 'Doe', '44 Vulcan Lane', 'Auckland'),
                        ('Jane', 'Doe', '44 Vulcan Lane', 'Auckland'),
                        ('Becky', 'Smith', '5 Freemans Lane', 'Kaitaia'),
                        ('Chris', 'Johnson', '18 Snow Drive', 'Christchurch');
                ";

        // Delete all rows
        /*$sql = "DELETE FROM Persons";*/


        /*if ($conn-&gt;query($sql) === TRUE) {
            echo "Database created successfully";
        } else {
            echo "Error creating database: " . $conn-&gt;error;
        }*/

        $conn-&gt;close();
    ?&gt;

    &lt;!-- &lt;div id="googleMap" style="height:500px;"&gt;&lt;/div&gt; --&gt;

    &lt;div id="find-vegan-products-page" style="height:900px;"&gt;
        &lt;div class="form-background"&gt;
        &lt;div class="container-fluid" style="padding: 40px;"&gt;
            &lt;h1&gt;Filter Your Search!&lt;/h1&gt;
            &lt;form role="form"&gt;
            &lt;div class="row"&gt;
                &lt;div class="form-group col-sm-6"&gt;
                   &lt;!-- &lt;select id="country-select" class="form-control input-control"&gt;&lt;/select&gt;--&gt;
                    &lt;div class="select"&gt;
                        &lt;span class="arr"&gt;&lt;/span&gt;
                        &lt;select data-bind=" options: _countries,
                                            optionsText: country.countryName,
                                            value: country.geonameId,
                                            optionsCaption: 'Choose...'"&gt;
                        &lt;/select&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
                &lt;div class="form-group col-sm-6"&gt;
                    &lt;div class="select"&gt;
                        &lt;span class="arr"&gt;&lt;/span&gt;
                        &lt;select id="city-select"&gt;
                        &lt;/select&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
            &lt;/div&gt;


            &lt;/form&gt;
         &lt;/div&gt;


&lt;/div&gt;

        &lt;/div&gt;
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>

<p>Typescript:</p>

<pre><code>class HomeViewModel {
    _countries = ko.observableArray();
    _cities = ko.observableArray();

    constructor(allCountries) {
        for (var index = 0; index &lt; allCountries.length; index++) {
            this._countries.push(allCountries[index]);
        }
    }
}

var _homeViewModel: HomeViewModel;

$(document).ready(function() {
    $("#city-select").append('&lt;option selected&gt;Any Region&lt;/option&gt;');
    $.ajax({
        url: "http://api.geonames.org/countryInfo?username=elion"
    }).then(function(allCountriesXML) {
        var allCountriesJSON = xml2json(allCountriesXML);
        var allCountries = JSON.parse(allCountriesJSON);
        _homeViewModel = new HomeViewModel(allCountries.geonames);
        ko.applyBindings(_homeViewModel);
    }
);
</code></pre>

<p>Here is the value of allCountries (a small sample of the copy paste from the console):</p>

<pre class="lang-none prettyprint-override"><code>[0 … 99]
0: Object
country: Object
areaInSqKm: "468.0"
capital: "Andorra la Vella"
continent: "EU"
continentName: "Europe"
countryCode: "AD"
countryName: "Andorra"
currencyCode: "EUR"
east: "1.786..."
</code></pre>

<p>If I change the html to:</p>

<pre><code>&lt;select data-bind=" options: _countries"&gt;
                        &lt;/select&gt;
</code></pre>

<p>It works, but the <code>&lt;select&gt;</code> shows [object][object] in the select box.</p>

<p>If I change the constructor of the viewModel to this:</p>

<pre><code>constructor(allCountries) {
        for (var index = 0; index &lt; allCountries.length; index++) {
            this._countries.push(allCountries[index].country.countryName);
        }
    }
</code></pre>

<p>And also keep the html as this:</p>

<pre><code>&lt;select data-bind=" options: _countries"&gt;
                        &lt;/select&gt;
</code></pre>

<p>It works but I don't have any value in the <code>&lt;select&gt;</code> because I have gotten rid of the array of javascript objects and made it an array of strings.</p>

<p>How do I bind the array of javascript objects to the <code>&lt;select&gt;</code> without it complaining that _countries is undefined? Is it happening because I am pushing into the _countries array after the document is ready, and in the html I am binding the ko.observableArray before the document is loaded? If so, I did try to initialise the ko.observableArray with a value but it did not fix the issue.</p>