Search code examples
mithril.js

How can I send init data to a Mithril component


I'm trying to initialize a Mithril component by setting the ID to fetch data from the server as follows:

// view/UserList.js
module.exports = {
    oninit: function(vnode) {
        console.log(vnode);
        var groupId = vnode.attrs.groupId;
        console.log('The group ID is '+groupId);
        User.loadUsersInGroup(groupId);
    },
    view: ...
}

I have the following:

var userList = require('./view/UserList');
m.mount(document.body, UserList, {groupId: 5});

But I get:

vnode.attrs is undefined

I tried to change it to:

var UserList = require('./view/UserList');
m.mount(document.body, m(UserList, {groupId: 5}));

But now I get:

m.mount(element, component) expects a component, not a vnode

How can I get the vnode.attrs to be populated correctly?


Solution

  • The correct way to send initialization data to a component can be found at https://mithril.js.org/mount.html#description.

    To pass arguments when mounting a component use:

    m.mount(element, {view: function () {return m(Component, attrs)}})
    

    So applied to this case, it would be:

    m.mount(document.body, {view: function() { return m(UserList, {groupId: 5}); }});
    

    Some other ways to do it are:

    const full   = {view: vnode => m('h1', vnode.attrs.test)}
    const short  = {view: v => m('h1', v.attrs.test)}
    const dest   = {view: ({attrs}) => m('h1', attrs.test)}
    const destf  = {view: ({attrs: {test}}) => m('h1', test)}
    
    m.mount(document.body, {
      view: () => [
        m(full,  {test: "full"}),
        m(short, {test: "short"}),
        m(dest,  {test: "destructured"}),
        m(destf, {test: "fully destructured"})
      ]
    })
    

    See them in action here. (courtesy of osban on the Mithril.js Gitter chat)