3

Trying out mithril.js for the first time, so apologies if this is simple question. I'm getting an error message,

Component template must return a virtual element, not an array, string, etc.

when I nest a map() derived components in another component.

Essentially, I was trying to create a layout like the following simplified example, where the address tags are derived from a .map() off of the ctrl.list() prop.

<Layout>
    <Left/>
    <Right>
      <Address>
      <Address>
  </Right>
</Layout>

Here's a jsfiddle that shows this. If you mount the "Right" component on its own, it renders fine. It's only when that component is nested in another component where it fails. What am I missing, and how do I debug this in the future?

https://jsfiddle.net/uLmt9qq7/

Barney
  • 16,181
  • 5
  • 62
  • 76
jgwl
  • 305
  • 1
  • 13

1 Answers1

1

In Mithril v0.2.X, a nested component (ie a component inside another) can't return an array of nodes1: it must return a single wrapping node with multiple children.

It looks like your code violates that rule by accident as a result of a typo in the Right view:

return m('.right-col'), 
  ctrl.list().map(function(addr){
    return m(Address, {addr: addr});
  })

In pseudo-code this is return {node}, [list], where the {node} is ditched and the view returns the unwrapped [list] - which triggers the error. It should be:

return m('.right-col', 
  ctrl.list().map(function(addr){
    return m(Address, {addr: addr});
  })
)

Here's a fixed fiddle.

1 This will no longer be the case in the rewritten Mithril v1.X, where component views can return lists of nodes directly.

Barney
  • 16,181
  • 5
  • 62
  • 76