Reputation: 1
I'm trying to POST a token and display the results as an ordered list. I would like the list to update onchange of the input. On page load the request POST is infinitely looping with error:
TypeError: ctrl.keys(...) is undefined
I suspect that my assumptions of how the data binding on the controller works are completely wrong.
//component
var tISM = {};
//model
tISM = {
Key: function(data) {
this.Id = m.prop(data.Id);
this.Name = m.prop(data.Name);
this.CreationTime = m.prop(data.CreationTime);
},
keys: function(token) {
return m.request({
method: "POST",
url: "key/list",
data: { "token": token },
type: tISM.Key
})
},
};
//controller
tISM.controller = function() {
// when this controller is updated perform a new POST for data by calling message?
var token = m.prop("xxx")
var keys = function() {
tISM.keys(this.token)
}
return { token, keys }
};
//view
tISM.view = function(ctrl) {
return m("div"), [
m("ol", ctrl.keys().map( function(key, index) {
return m("li", key.Id, key.Name, key.CreationTime)
})),
m("input", {
onchange: m.withAttr("value", ctrl.token)
})
]
};
//initialize
m.mount(document.getElementById("app"), tISM);
<script src="http://cdnjs.cloudflare.com/ajax/libs/mithril/0.2.5/mithril.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Mithril App</title>
<script src="mithril.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
Upvotes: 0
Views: 248
Reputation: 1
My problem was I don't know javascript. This works:
//component
var tISM = {};
//model
tISM.Key = function(data) {
this.Id = m.prop(data.Id);
this.Name = m.prop(data.Name);
this.CreationTime = m.prop(data.CreationTime);
}
tISM = {
keys: function(token) {
return m.request({
method: "POST",
url: "key/list",
data: { "token": token },
type: tISM.Key
})
},
};
//controller
tISM.controller = function() {
this.token = m.prop("")
this.keys = m.prop([])
this.updateToken = function(token) {
this.token(token)
tISM.keys(this.token).then(this.keys)
}.bind(this)
};
//view
tISM.view = function(ctrl) {
return m("div"), [
m("input", {
oninput: m.withAttr("value", ctrl.updateToken)
}),
m("ol", ctrl.keys().map( function(key, index) {
return m("li", key.Id, key.Name, key.CreationTime)
})),
]
};
//initialize
m.mount(document.getElementById("app"), tISM);
Upvotes: 0
Reputation: 1069
m.request() returns a deferred, not the value itself. I have a snippet below that shows one way of getting the values out. I explicitly replaced the m.request() with deferred calls under the hood, and a timeout rather than a post.
//component
var tISM = {};
//model
tISM = {
Key: function(data) {
this.Id = m.prop(data.Id);
this.Name = m.prop(data.Name);
this.CreationTime = m.prop(data.CreationTime);
},
keys: function(token) {
m.startComputation()
var d = m.deferred();
setTimeout(function() {
d.resolve([1,2,3]);
m.endComputation();
}, 1000);
return d.promise;
}
};
//controller
tISM.controller = function() {
// when this controller is updated perform a new POST for data by calling message?
var token = m.prop("xxx")
var keys = m.prop([]);
tISM.keys(this.token).then(keys)
return {
token: token,
keys: keys
}
return { token, keys }
};
//view
tISM.view = function(ctrl) {
return m("div"), [
m("ol", ctrl.keys().map( function(key, index) {
return m("li", key.Id, key.Name, key.CreationTime)
})),
m("input", {
onchange: m.withAttr("value", ctrl.token)
})
]
};
//initialize
m.mount(document.getElementById("app"), tISM);
<script src="http://cdnjs.cloudflare.com/ajax/libs/mithril/0.2.5/mithril.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Mithril App</title>
<script src="mithril.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
Upvotes: 0