-
Notifications
You must be signed in to change notification settings - Fork 27.1k
ActivatedRoute.title observable does not emit changes #51401
Description
Which @angular/* package(s) are the source of the bug?
router
Is this a regression?
No
Description
The problem is that having RouteConfig.title configured as ResolveFn does not emit updates in the component via ActivatedRoute.title (which is of Observable type).
The correct/updated title value though is available in ActivatedRoute.snapshot.title.
I.e.
A route like
{
path: ':id',
component: SomeComponent,
title: (snapshot) => snapshot.paramMap.get('id'),
}and a component
export class SomeComponent implements OnInit {
constructor(readonly route: ActivatedRoute) {
route.params.pipe(map(() => route.snapshot.title)).subscribe(console.log); // logs every time params is updated
route.title.subscribe(console.log); // only initial value is logged
}I would expect both observable should log same values simultaneously, i.e. title Observable should be in sync with current snapshot.
Please provide a link to a minimal reproduction of the bug
https://stackblitz.com/edit/stackblitz-starters-v2ndqs
Please provide the exception or error you saw
No response
Please provide the environment you discovered this bug in (run ng version)
Angular CLI: 15.2.9
Node: 18.15.0
Package Manager: npm 9.5.0
OS: win32 x64
Angular: 15.2.9
... animations, cdk, cli, common, compiler, compiler-cli, core
... forms, language-service, platform-browser
... platform-browser-dynamic, router
Package Version
---------------------------------------------------------
@angular-devkit/architect 0.1502.9
@angular-devkit/build-angular 15.2.9
@angular-devkit/core 15.2.9
@angular-devkit/schematics 15.2.9
@schematics/angular 15.2.9
rxjs 7.8.1
typescript 4.9.5
Anything else?
I believe the cause of the issue is next:
angular/packages/router/src/router_state.ts
Lines 476 to 478 in 77504f1
| if (!shallowEqual(currentSnapshot.data, nextSnapshot.data)) { | |
| route.dataSubject.next(nextSnapshot.data); | |
| } |
AFAIK the title is resolved as part of route's data and stored there under symbol Symbol(RouteTitle).
ActivatedRoute.title set as projection from ActivatedRoute.data[Symbol(RouteTitle)]
So in order for ActivatedRoute.title to emit a new value the ActivatedRoute.data should emit a new value. But, as we can see above, the ActivatedRoute.data only updated when shallowEqual(currentSnapshot.data, nextSnapshot.data) == false. The thing is that symbols are not enumerated as keys of data object thus not checked for equality.
The very naive solution might be to update check as following:
if (!shallowEqual(currentSnapshot.data, nextSnapshot.data) || currentSnapshot.title !== nextSnapshot.title) {
route.dataSubject.next(nextSnapshot.data);
}