diff --git a/packages/ember-routing/lib/system/route.js b/packages/ember-routing/lib/system/route.js index 5b3e15e58ed..9e813e3568e 100644 --- a/packages/ember-routing/lib/system/route.js +++ b/packages/ember-routing/lib/system/route.js @@ -811,11 +811,17 @@ var Route = EmberObject.extend(ActionHandler, Evented, { var handlerInfos = transition.state.handlerInfos; var router = this.router; - var qpMeta = router._queryParamsFor(handlerInfos[handlerInfos.length - 1].name); + var qpMeta; var changes = router._qpUpdates; var replaceUrl; - stashParamNames(router, handlerInfos); + // handlerInfos are empty for some no-op/queryParamsOnly transitions + if (!handlerInfos.length) { + qpMeta = router._queryParamsFor(this.routeName); + } else { + qpMeta = router._queryParamsFor(handlerInfos[handlerInfos.length - 1].name); + stashParamNames(router, handlerInfos); + } for (var i = 0; i < qpMeta.qps.length; ++i) { var qp = qpMeta.qps[i]; @@ -823,6 +829,9 @@ var Route = EmberObject.extend(ActionHandler, Evented, { var controller = route.controller; var presentKey = qp.urlKey in params && qp.urlKey; + if (!controller) { + controller = route._addController(); + } // Do a reverse lookup to see if the changed query // param URL key corresponds to a QP property on // this controller. @@ -1197,13 +1206,16 @@ var Route = EmberObject.extend(ActionHandler, Evented, { } }, + /** - This hook is the entry point for router.js + Adds query param observers to controller and sets this.controller prop + @method _addController + @param {Object} context @private - @method setup */ - setup(context, transition) { + + _addController(context) { var controller; var controllerName = this.controllerName || this.routeName; @@ -1215,12 +1227,25 @@ var Route = EmberObject.extend(ActionHandler, Evented, { controller = definedController; } + var propNames = get(this, '_qp.propertyNames'); + addQueryParamsObservers(controller, propNames); + this.controller = controller; + return controller; + }, + + /** + This hook is the entry point for router.js + + @private + @method setup + */ + setup(context, transition) { + var controller = this.controller; + // Assign the route's controller so that it can more easily be // referenced in action handlers. Side effects. Side effects everywhere. - if (!this.controller) { - var propNames = get(this, '_qp.propertyNames'); - addQueryParamsObservers(controller, propNames); - this.controller = controller; + if (!controller) { + controller = this._addController(context); } var queryParams = get(this, '_qp'); diff --git a/packages/ember-routing/lib/system/router.js b/packages/ember-routing/lib/system/router.js index a142adf7ffb..ae079ba30f7 100644 --- a/packages/ember-routing/lib/system/router.js +++ b/packages/ember-routing/lib/system/router.js @@ -987,6 +987,9 @@ function calculatePostTransitionState(emberRouter, leafRouteName, contexts) { function updatePaths(router) { let infos = router.router.currentHandlerInfos; + + if (!Array.isArray(infos) || infos.length === 0) { return; } + let path = EmberRouter._routePath(infos); let currentRouteName = infos[infos.length - 1].name; diff --git a/packages/ember/tests/routing/query_params_test.js b/packages/ember/tests/routing/query_params_test.js index cb8d80c0861..ace4658588b 100644 --- a/packages/ember/tests/routing/query_params_test.js +++ b/packages/ember/tests/routing/query_params_test.js @@ -622,6 +622,24 @@ if (isEnabled('ember-routing-route-configured-query-params')) { equal(router.get('location.path'), '/?foo=false', 'shorhand supported (bool)'); }); + QUnit.test('transitionTo called from route.beforeModel hook supports query params when configuration occurs on the route', function() { + App.IndexRoute = Route.extend({ + queryParams: { + foo: { + defaultValue: 'lol' + } + }, + beforeModel(tranition) { + this.transitionTo({queryParams: { foo: 'bar' }}); + } + }); + + startingURL = "/?foo=lol"; + bootApplication(); + + equal(router.get('location.path'), '/?foo=bar'); + }); + QUnit.test('transitionTo supports query params (multiple) when configuration occurs on the route', function() { App.IndexRoute = Route.extend({ queryParams: { @@ -2852,6 +2870,25 @@ if (isEnabled('ember-routing-route-configured-query-params')) { equal(router.get('location.path'), '/?foo=false', 'shorhand supported (bool)'); }); + QUnit.test('transitionTo called from route.beforeModel hook supports query params', function() { + App.IndexController = Controller.extend({ + queryParams: ['foo'], + foo: 'lol' + }); + + App.IndexRoute = Route.extend({ + beforeModel: function(transition) { + this.transitionTo({queryParams: { foo: 'bar' }}); + } + }); + startingURL = '/?foo=wat'; + + bootApplication(); + + equal(router.get('location.path'), '/?foo=bar'); + }); + + QUnit.test('transitionTo supports query params (multiple)', function() { App.IndexController = Controller.extend({ queryParams: ['foo', 'bar'],