title: Knockout bindings are not updating
body: <p>I'm playing around with an app that gets playlistItem data from the youtube api and lists all titles in the playlist on a page using knockout.js. I can get the list to load just fine, but I'm running into some issues while trying to add some extra functionality to the app. </p>
  
  <p>Things I'm trying to add are a count of the total number of titles in the playlist and an input field that lets the user load another playlist. I currently can get neither to work. 
  Here's the app.js file:</p>
  
  <pre><code>// global variables
  var ytResults=[];
  var pageToken;
  //var clipCount=ko.observable('');
  var clipsDone=0; 
  var ytPlaylistID='PLpmQJ2D10iJx_GEYNZwAON38cluj0dNj4';
  
  // function to create clip objects
  var clip=function(data){
      this.clipTitle=ko.observable(data.title);
  };
  
  function Model(){
  var self=this;
  //Create an observable array to store a list of clip objects
  self.clipList=ko.observableArray([]);
  self.clipCount=ko.observable('');
  }
  var model =new Model();
  
  function ViewModel(){
  var self = this;
  self.errorMessage=ko.observable('');
  self.loadPlaylist=ko.observable('');
  errorHandling=function(){
      self.errorMessage("Can't load the list and app");
  };
  
  fillList=function(){
      for(i=0;i&lt;ytResults.length;i++){
          var clipData={
              title: ytResults[i]
          };
          model.clipList.push(new clip(clipData));
      };
  };
  
  var ytConnector=(function(){
      var searchYtRequest=function(requestPayload, callback){
          $.ajax({
              url: requestPayload.url,
              type: requestPayload.method,
          }).done(function(data){
              //console.log(data);
              model.clipCount=data.pageInfo.totalResults;
              ytResults.length=0;
              for(i=0;i&lt;data.items.length;i++){
                  ytResults=ytResults.concat(data.items[i].snippet.title);
              };
              fillList();
              pageToken=data.nextPageToken;
              clipsDone=clipsDone+50;
              if(clipsDone&lt;model.clipCount){
                  ytConnector.fetchDataFromYt();
              };
          }).fail(function(jqxhr, textStatus, error) {
              // Let empty results set indicate problem with load.
              // If there is no callback - there are no UI dependencies
              self.errorMessage("Failed to load: " + textStatus + ", " + error);
          }).always(function() {
              typeof callback === 'function' &amp;&amp; callback(ytResults);
          });
      };
      // get playlist data from youtube
      function fetchDataFromYt(){
          if(pageToken!=null){
              thisUrl='https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&amp;maxResults=50&amp;playlistId='+ytPlaylistID+'&amp;key=AIzaSyBFrCeUpPitoT6eOk_mq6Uza6etWtAH0oQ&amp;pageToken='+pageToken;
          }else{
              thisUrl='https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&amp;maxResults=50&amp;playlistId='+ytPlaylistID+'&amp;key=AIzaSyBFrCeUpPitoT6eOk_mq6Uza6etWtAH0oQ';
          };
          var requestData = {
              url: thisUrl,
              method: 'GET',
          };
          searchYtRequest(requestData);
      }return{
          fetchDataFromYt: fetchDataFromYt,
      };
  })();
  ytConnector.fetchDataFromYt();
  
  thisPlaylist=function(){
      ytPlaylistID=self.loadPlaylist();
      console.log('playlist ID: '+ytPlaylistID);
  };
  }
  ko.applyBindings(new ViewModel());
  
  // PLpmQJ2D10iJzd1SPy7FlaaBFt07fhLSL3
  </code></pre>
  
  <p>Here's the html:</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html lang="en"&gt;
  &lt;head&gt;
  &lt;meta charset="UTF-8"&gt;
  &lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&gt;
  &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;
  &lt;link href="https://fonts.googleapis.com/css?family=Telex|Aldrich" rel="stylesheet"&gt;
  &lt;link href="css/style.css" rel="stylesheet"&gt;
  &lt;title&gt;Youtube playlist&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
  &lt;div class="container"&gt;
      &lt;div class="errorMsg" data-bind="text: errorMessage, visible: errorMessage"&gt;
      &lt;/div&gt;
      &lt;div class="form-holder"&gt;
          &lt;form data-bind="submit: thisPlaylist"&gt;
                  playlist ID: &lt;input type="text" size="50" data-bind="value: loadPlaylist, valueUpdate: 'afterkeydown'"&gt;
              &lt;button type="submit" data-bind="enable: loadPlaylist().length&gt;0"&gt;submit&lt;/button&gt;
          &lt;/form&gt;
      &lt;/div&gt;
      &lt;div class="info-holder"&gt;
          clips in playlist:&lt;span data-bind="text: model.clipCount"&gt;&lt;/span&gt;
      &lt;/div&gt;
      &lt;ul class="listDiv" data-bind="foreach: model.clipList"&gt;
          &lt;li data-bind="text: clipTitle"&gt;
      &lt;/ul&gt;
  &lt;/div&gt;
  &lt;script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"&gt;&lt;/script&gt;
  &lt;script src="js/lib/knockout-3.2.0.js"&gt;&lt;/script&gt;
  &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha1.js"&gt;&lt;/script&gt;
  &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js"&gt;&lt;/script&gt;
  &lt;script src="js/oauth-1.0a.js"&gt;&lt;/script&gt;
  &lt;script src="js/app.js"&gt;&lt;/script&gt;
  &lt;/body&gt;
  </code></pre>