member2 member2 - 8 days ago 5
Ajax Question

Ajax async get request in Riotjs

I cant get my Code to work with async get requests.
I want to load the JSON Objects which I get through a GET request in a Table in my File todo.tag.html.
My Problem is how can i pass the parameters. I want to pass the parameters to my riot tag but i dont know how. I tried it with each="{ allTodos() }" in my tag. This method actually works if i set async:false but not with async true.
allTodos is the method which gets the JSON objects. Anyone know what i can do?
This is my (simplified) Code
index.html:

<!DOCTYPE html>
<head>

<link rel="stylesheet" type="text/css" href="./jquery-ui.css">
<link rel="stylesheet" type="text/css" href="./style.css">
<link rel="stylesheet" type="text/css" href="./stylesheet.css">
<script src="./jquery-1.12.4.js"></script>
<script src="./jquery-ui.js"></script>

</head>
<body>

<script src="js/riot+compiler.min.js"></script>
<script type="riot/tag" src="todo-form.tag.html"></script>
<script type="riot/tag" src="todo.tag.html"></script>
</script>
<script>riot.mount('todoForm');</script>
<form>
<todo-form><todo-form>
<form>
</body>
</html>


todo.tag.html:

<todo>
<table style="width:100%">
<tr>
<td><label><input type="checkbox" checked={ done }> { title }</label> </td>
<td><p>{ due_date } <button type="button">Delete</button></p></td>
</tr>

</table>


</todo>


todo-form.tag.html

<todo-form>


<fieldset class="Issues">
<legend>Issues</legend>
<ul>
<todo each="{ allTodos() }"> </todo> // This here is the problem
</ul>
</fieldset>


<script>

// return all todos
allTodos(){
var test = [];

var url = 'http://myurl.com/projects'; //random adress

$.ajax({
url: url,
type: "GET",
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(data) {
test = data;
}
});

return test;
}
</script>

</todo-form>


Thats how my JSON objects look

[
{

"done": true,
"title": "tests",
"due_date": "2016-11-20T23:00:00.000Z"
},
{

"done": true,
"title": "tests2",
"due_date": "2016-11-20T23:00:00.000Z"
}
]

Answer

For tag communication you can send parameters in the tag and then in the child use the opts object.

Here is a sample (removing the async functionality as that is another problem) As you can see I used 'todo in todos' to get a reference for the current record and then I pass a parameter called t with the record.

<todo each="{ todo in todos }" t={todo} > </todo>

Then in the todo tag I access the records using opts and t that is the parameter.

{ opts.t.due_date }

Also I used on('mount') that it will execute when mounting the tag, and this.update() to force an update. and self= this to maintain the context

var self = this
this.todos = []
this.on('mount', function(){
  self.todos = self.allTodos()
  self.update()
})

Here is the simplified code

<todo-form>
  <fieldset>
    <legend>Issues</legend>
    <ul>
      <todo each="{ todo in todos }" t={todo} > </todo>
    </ul> 
  </fieldset>

  <script>
    var self = this
    this.todos = []
    this.on('mount', function(){
      self.todos = self.allTodos()
      self.update()
    })
    allTodos(){
      var test = [{done:'true', due_date:'11', title:'the title'}, {done:'true', due_date:'11', title:'the title'}]
      return test
    }
  </script>
</todo-form>

<todo>
  <table>
    <tr>
      <td><label><input type="checkbox" checked={ opts.t.done }> { opts.t.title }</label> </td>
      <td><p>{ opts.t.due_date } <button type="button">Delete</button></p></td>
    </tr>
  </table>
</todo>

http://plnkr.co/edit/PqLFIduigsOYd2XQ5LWv?p=preview

And about the async function I think that you can call self.update() in the success callback function to rerender the todos and just assign the data to self.todos = data

var self = this
allTodos(){
  var url = 'http://myurl.com/projects'; //random adress
   $.ajax({
        url: url,
        type: "GET",
        dataType: "json",
        contentType: "application/json; charset=utf-8",
        success: function(data) {
          self.todos = data
          self.update()
        }
    });
}
Comments