zealot
zealot

Reputation: 51

Knockout did not render template with my data

Stuck with javascipt's knockout library. So, I want to implement simple forum. I have javascript file with two ajax requests, for topics and for posts. And I have html template.

function dealModel() {
  var self = this;
  self.board = ko.observableArray([]);
  var res = [];

  $.getJSON("http://someaddress/threads", function(data) {
    $.each(data, function(i, thread) {
      var js = jQuery.parseJSON(thread);
      js.posts = ko.observableArray([]);
      var postres = []
      $.getJSON("http://someadress/posts/" + js.id, function(postdata) {
        $.each(postdata, function(idx, post){
          var jspost = jQuery.parseJSON(post);
          postres.push(jspost);
        })
      })

      js.posts(postres);
      res.push(js);
    })

    self.board(res);
  })
}
$(document).ready(function(){
  ko.applyBindings(new dealModel());
});
var testdata = [{text : "text 1"} , {text : "text2"}]

This is my js code. It perfectly works with topics, but when I put my posts, my observable array "posts" already empty. For test I created test array "testdata" (below), and pass in my observable array. And, javascript work perfectly. Here is my template

<!DOCTYPE html>
<html>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"></script>

<script type="text/javascript" src="ajaxknockout.js"></script>
</head>
 <body>
    <div class='board'>
  <div class='threads' data-bind="foreach: board">

  <p data-bind="text: title"></p>

  <div  class= "posts" data-bind="foreach: $data.posts">

    <p data-bind="text: text"> </p>
    </div>
  </div>


</div>
 </body>>
</html>

So, I think something bad with my posts JSON. Here it is.

["{\"createTime\": \"Monday, 04. January 2016 05:53PM\",\"thread_id\": \"2\",\"text\": \"post 1\",\"id\": \"4\"}", "{\"createTime\": \"Monday, 04. January 2016 05:53PM\",\"thread_id\": \"2\",\"text\": \"post 2\",\"id\": \"5\"}", "{\"createTime\": \"Monday, 04. January 2016 05:53PM\",\"thread_id\": \"2\",\"text\": \"post 3\",\"id\": \"6\"}"]

SO, I have a question. Whats wrong with my code? Why knockout understand my testdata, but completly reject production data?

Upvotes: 1

Views: 118

Answers (1)

Nikolay Ermakov
Nikolay Ermakov

Reputation: 5061

That's because this part of your first json request:

js.posts(postres);

executes ahead of callback from your second json request where you are pulling posts. You have to change that so the posts array is populated before doing js.posts(postres);, e.g like so:

$.getJSON("http://someadress/posts/" + js.id, function(postdata) {
    $.each(postdata, function(idx, post){
        var jspost = jQuery.parseJSON(post);
        postres.push(jspost);
    })
    js.posts(postres);
})

Upvotes: 1

Related Questions