jtmanteo
jtmanteo

Reputation: 151

Why won't my MithrilJS UI render unless I call redraw after a programmatic redirect?

Here is a snippet of view code. Why won't it work without the m.redraw()? If I don't call that, the route changes and the login controller loads, but nothing is rendered into the DOM.

home.view = function(ctrl) {
    console.log('in home view');
    if (!mo_portal.logged_in) {
        console.log('redirecting to login');
        m.route("/login");
        m.redraw();
        return;
    }

    return m("div","HOME");
}

Upvotes: 0

Views: 740

Answers (2)

Barney
Barney

Reputation: 16456

Changing route will always trigger a redraw. If you're not seeing the login page view without manually calling m.redraw it's probably down to bugs in the login controller or view that happen during the route change redraw - bugs whose failure conditions are reset when you call m.redraw again.

Here's an extension of your code with a login view and controller. mo_portal.logged_in is set to true or false depending on whether the user is one in the usersList or not, so we can test success and failure.

I took out the m.redraw (I also put the redirect logic in the home controller) and everything works fine.

var usersList = [
    'john',
    'alexia'
];

var mo_portal = {
    username : '',
    logged_in: false
};

var login = {};
login.controller = function(){
    this.username = function( input ){
        if( arguments.length ){
            mo_portal.username = input;
            
            mo_portal.logged_in = !!~usersList.indexOf( input );
        }
        
        return mo_portal.username;
    };
};
login.view = function(ctrl){
    console.log('in login view');
    
    return [
        m( 'input', { oninput : m.withAttr( 'value', ctrl.username ), value : ctrl.username() } ),
        m( 'a[href=/home]', { config : m.route }, 'Login' )
    ];
};

var home = {};
home.controller = function(){
    if (!mo_portal.logged_in) {
        console.log('redirecting to login');
        m.route("/login");
    }
};
home.view = function(ctrl) {
    console.log('in home view');

    return m("div","HOME");
};

m.route( document.body, '/login', {
    '/login' : login,
    '/home'  : home
} );
<script src="https://rawgit.com/lhorie/mithril.js/next/mithril.js"></script>

Upvotes: 3

Stephan Hoyer
Stephan Hoyer

Reputation: 4928

I think that's not how mithril is going to be used. Mithril does not expect a view update (aka redraw) during ongoing view construction.

I suppose you should do the route-change in the related controller.

Keep in mind, that a view is rendered evertime the page changes somehow. You probably don't want to check the login state evert time.

Upvotes: 1

Related Questions