{"action":"created","issue":{"url":"https://api.github.com/repos/lhorie/mithril.js/issues/1095","repository_url":"https://api.github.com/repos/lhorie/mithril.js","labels_url":"https://api.github.com/repos/lhorie/mithril.js/issues/1095/labels{/name}","comments_url":"https://api.github.com/repos/lhorie/mithril.js/issues/1095/comments","events_url":"https://api.github.com/repos/lhorie/mithril.js/issues/1095/events","html_url":"https://github.com/lhorie/mithril.js/issues/1095","id":158532312,"number":1095,"title":"Add hook to router","user":{"login":"s3ththompson","id":970121,"avatar_url":"https://avatars.githubusercontent.com/u/970121?v=3","gravatar_id":"","url":"https://api.github.com/users/s3ththompson","html_url":"https://github.com/s3ththompson","followers_url":"https://api.github.com/users/s3ththompson/followers","following_url":"https://api.github.com/users/s3ththompson/following{/other_user}","gists_url":"https://api.github.com/users/s3ththompson/gists{/gist_id}","starred_url":"https://api.github.com/users/s3ththompson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/s3ththompson/subscriptions","organizations_url":"https://api.github.com/users/s3ththompson/orgs","repos_url":"https://api.github.com/users/s3ththompson/repos","events_url":"https://api.github.com/users/s3ththompson/events{/privacy}","received_events_url":"https://api.github.com/users/s3ththompson/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/lhorie/mithril.js/labels/discussion","name":"discussion","color":"d4c5f9"},{"url":"https://api.github.com/repos/lhorie/mithril.js/labels/enhancement","name":"enhancement","color":"84b6eb"},{"url":"https://api.github.com/repos/lhorie/mithril.js/labels/rewrite","name":"rewrite","color":"0e8a16"}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/lhorie/mithril.js/milestones/1","html_url":"https://github.com/lhorie/mithril.js/milestones/Rewrite","labels_url":"https://api.github.com/repos/lhorie/mithril.js/milestones/1/labels","id":1835772,"number":1,"title":"Rewrite","description":"Issues and pull requests geared towards completing the rewrite.","creator":{"login":"isiahmeadows","id":4483844,"avatar_url":"https://avatars.githubusercontent.com/u/4483844?v=3","gravatar_id":"","url":"https://api.github.com/users/isiahmeadows","html_url":"https://github.com/isiahmeadows","followers_url":"https://api.github.com/users/isiahmeadows/followers","following_url":"https://api.github.com/users/isiahmeadows/following{/other_user}","gists_url":"https://api.github.com/users/isiahmeadows/gists{/gist_id}","starred_url":"https://api.github.com/users/isiahmeadows/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/isiahmeadows/subscriptions","organizations_url":"https://api.github.com/users/isiahmeadows/orgs","repos_url":"https://api.github.com/users/isiahmeadows/repos","events_url":"https://api.github.com/users/isiahmeadows/events{/privacy}","received_events_url":"https://api.github.com/users/isiahmeadows/received_events","type":"User","site_admin":false},"open_issues":8,"closed_issues":9,"state":"open","created_at":"2016-06-18T08:01:00Z","updated_at":"2016-07-06T13:15:29Z","due_on":null,"closed_at":null},"comments":22,"created_at":"2016-06-05T01:20:44Z","updated_at":"2016-07-11T14:02:23Z","closed_at":null,"body":"A feature request for the Mithril rewrite:\r\n\r\nI love the simplicity of the current router, but I would like to expose a hook that runs after a route has been resolved but before the associated component has been rendered. The feature would be useful for implementing a few common patterns:\r\n- `/` routes to a landing page if the user is logged out, but `/dashboard` if the user is logged in\r\n- `/dashboard` routes to a dashboard if user is logged in, but `/login` if user is logged out\r\n\r\nThere is lots of precedent for this type of hook in other routers. See, for example, [`onenter`](https://github.com/reactjs/react-router/blob/master/docs/API.md#onenternextstate-replace-callback) in react-router and the ability to extend [`router.execute`](http://backbonejs.org/#Router-execute) in Backbone.\r\n\r\n##### Current solution in Mithril\r\n\r\n```js\r\nvar Dashboard = {\r\n  oninit: function(vnode) {\r\n      if (!Auth.loggedIn()) {\r\n        m.route.setPath(\"/login\");\r\n      }\r\n  }\r\n// *** view code ***\r\n}\r\n```\r\n\r\nUnfortunately, since `setPath` asynchronously triggers a reroute *only after the `window.onpopstate` event fires*, the dashboard component above renders to the screen for a split second before the login page is loaded.\r\n\r\n##### Propsed API Options\r\n\r\nAdd an `onroute` hook to components that runs before the component is rendered and has the option to redirect to another route without rendering the component?\r\n\r\nAlternatively, if `oninit` returns false, prevent rendering of the component?"},"comment":{"url":"https://api.github.com/repos/lhorie/mithril.js/issues/comments/231743262","html_url":"https://github.com/lhorie/mithril.js/issues/1095#issuecomment-231743262","issue_url":"https://api.github.com/repos/lhorie/mithril.js/issues/1095","id":231743262,"user":{"login":"lhorie","id":1637573,"avatar_url":"https://avatars.githubusercontent.com/u/1637573?v=3","gravatar_id":"","url":"https://api.github.com/users/lhorie","html_url":"https://github.com/lhorie","followers_url":"https://api.github.com/users/lhorie/followers","following_url":"https://api.github.com/users/lhorie/following{/other_user}","gists_url":"https://api.github.com/users/lhorie/gists{/gist_id}","starred_url":"https://api.github.com/users/lhorie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lhorie/subscriptions","organizations_url":"https://api.github.com/users/lhorie/orgs","repos_url":"https://api.github.com/users/lhorie/repos","events_url":"https://api.github.com/users/lhorie/events{/privacy}","received_events_url":"https://api.github.com/users/lhorie/received_events","type":"User","site_admin":false},"created_at":"2016-07-11T14:02:23Z","updated_at":"2016-07-11T14:02:23Z","body":"update: I added experimental support for `resolve` and `render` hooks\r\n\r\nUsage:\r\n```javascript\r\nvar MyLayout = {\r\n  view: function(vnode) {\r\n    return m(\".layout\", vnode.attrs.body)\r\n  }\r\n}\r\nvar MyComponent = {\r\n  view: function() {return \"hello\"}\r\n}\r\n\r\nm.route(document.body, \"/\", {\r\n  \"/\": {\r\n    resolve: function(use, args, path, route) { //runs on route change\r\n      use(MyComponent) //may be called asynchronously for code splitting\r\n    },\r\n    render: function(vnode) { //vnode is m(MyComponent, routerArgs) where MyComponent is the value passed to `use()` above\r\n      return m(Layout, {body: vnode}) //runs on every redraw, like component `view` methods\r\n    }\r\n  },\r\n  \"/foo\": {\r\n    render: function() {\r\n      return m(Layout, {body: MyComponent}) // `resolve` method is optional\r\n    }\r\n  },\r\n  \"/bar\": {\r\n    resolve: function(use) {\r\n      use(MyComponent) // `render` method is optional too, so this renders MyComponent without layout\r\n    }\r\n  }\r\n})\r\n```"}}
{"actor":{"display_login":"lhorie"}}