Skip to content

Commit 7f11a35

Browse files
authored
Fix RouterService#isActive (#20954)
1 parent 2fe9ba3 commit 7f11a35

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

packages/@ember/routing/router-service.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ class RouterService extends Service.extend(Evented) {
311311
*/
312312
isActive(...args: RouteArgs) {
313313
let { routeName, models, queryParams } = extractRouteArgs(args);
314+
this._router.setupRouter();
314315
let routerMicrolib = this._router._routerMicrolib;
315316

316317
// When using isActive() in a getter, we want to entagle with the auto-tracking system

packages/ember/tests/routing/router_service_test/isActive_test.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Controller from '@ember/controller';
2+
import { Component } from '@ember/-internals/glimmer';
23
import { RouterTestCase, moduleFor } from 'internal-test-helpers';
34
import Service, { service } from '@ember/service';
45

@@ -168,5 +169,47 @@ moduleFor(
168169
assert.deepEqual(qp.queryParams, { sort: 'ascending' });
169170
});
170171
}
172+
173+
['@test RouterService#isActive works reliably during component rendering before router initialization'](
174+
assert
175+
) {
176+
assert.expect(1);
177+
178+
// This simulates the scenario where isActive is called during component rendering
179+
// before the router has been fully set up, which used to throw an error
180+
181+
let componentInstance;
182+
183+
this.addTemplate('parent.index', '{{foo-component}}');
184+
185+
this.addComponent('foo-component', {
186+
ComponentClass: class extends Component {
187+
@service('router')
188+
routerService;
189+
190+
init() {
191+
super.init();
192+
componentInstance = this;
193+
}
194+
195+
get isRouteActive() {
196+
// This used to throw "Cannot read properties of undefined (reading 'isActiveIntent')"
197+
// before setupRouter() was added to the isActive method
198+
return this.routerService.isActive('parent.child');
199+
}
200+
},
201+
template: `{{this.isRouteActive}}`,
202+
});
203+
204+
return this.visit('/').then(() => {
205+
// The test passes if no error is thrown during rendering
206+
// and isActive returns a boolean value
207+
assert.strictEqual(
208+
typeof componentInstance.isRouteActive,
209+
'boolean',
210+
'isActive should return a boolean value without throwing an error'
211+
);
212+
});
213+
}
171214
}
172215
);

0 commit comments

Comments
 (0)