Theodore Cowan
Theodore Cowan

Reputation: 1

mithril.js stuck in loop calling controller

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

Answers (2)

Theodore Cowan
Theodore Cowan

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

Jason
Jason

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

Related Questions