angular: The behavior of ActivatedRoute's Observables are not documented (only emit when shallow equality check fails)
🐞 bug report
Description
I have two modules:
const routes: Routes = [
{ path: 'users', loadChildren: () => import('./modules/users/users.module').then(m => m.UsersModule) },
{ path: 'chats', loadChildren: () => import('./modules/chats/chats.module').then(m => m.ChatsModule) }
];
Those modules contains some routes with the resolvers. E.g:
users-routing.module.ts
const routes: Routes = [
{
path: '',
component: UsersComponent,
resolve: {
users: UsersResolver
},
runGuardsAndResolvers: 'always', // <-- Resolver works fine, always
children: [
{ path: 'create', component: UsersCreateComponent },
{ path: 'update/:token', resolve: { user: UserResolver }, component: UsersUpdateComponent },
{ path: 'details/:token', resolve: { user: UserResolver }, component: UsersDetailsComponent },
]
},
];
users.resolver.ts
import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { take } from 'rxjs/operators';
import { UsersService } from '../services/users.service';
@Injectable({
providedIn: 'root'
})
export class UsersResolver implements Resolve<any[]> {
constructor(private usersService: UsersService) { }
resolve(route: ActivatedRouteSnapshot): Observable<any[]> {
return this.usersService.fetchUsers().pipe(take(1));
}
}
When i navigate from the children path to the parent path e.g. /users
, UsersResolver
works fine, but the code listed below won’t works if a resolver returns an empty array:
users.component.ts
ngOnInit(): void {
// Doesn't fired up when a resolver returns an empty data.users array
// But if i have at least one object in the array, then this code works fine
this.route.data.subscribe(data => {
this.users = data.users;
console.log(this.users);
});
}
The important thing is that resolver sends requests to the server, but this.route.data.subscribe(...)
still doesn’t works when resolver returns an empty array. A bug exists only between the parent <-> children navigation. Navigation between the modules and this.route.data.subscribe(...)
with the resolvers works fine.
Minimal Reproduction
Thanks to @destus90: https://stackblitz.com/edit/angular-ivy-9ajhzu?file=src%2Fapp%2Fmodules%2Fusers.service.ts
My previous report, same problem: #37365
Expected behaviour
this.router.data.subscribe(...)
should works if a resolver returns an empty array between the parent <-> children navigation.
🌍 Your Environment
Angular Version:
Angular CLI: 9.0.7
Node: 14.15.3
OS: linux x64
Angular:
...
Ivy Workspace:
Package Version
------------------------------------------------------
@angular-devkit/architect 0.900.7
@angular-devkit/core 9.0.7
@angular-devkit/schematics 9.0.7
@schematics/angular 9.0.7
@schematics/update 0.900.7
rxjs 6.5.3
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 20 (7 by maintainers)
Commits related to this issue
- docs: document shallow equality emit for ActivatedRoute fixes #40769 — committed to atscott/angular by atscott 3 years ago
- docs: document shallow equality emit for ActivatedRoute fixes #40769 — committed to atscott/angular by atscott 3 years ago
- docs: document shallow equality emit for ActivatedRoute (#42280) fixes #40769 PR Close #42280 — committed to angular/angular by atscott 3 years ago
- docs: document shallow equality emit for ActivatedRoute (#42280) fixes #40769 PR Close #42280 — committed to umairhm/angular by atscott 3 years ago
- docs: document shallow equality emit for ActivatedRoute (#42280) fixes #40769 PR Close #42280 — committed to iRealNirmal/angular by atscott 3 years ago
I found out that when a resolver returns the same value as in a previous call a subscriber for
route.data
is not notified. Once I return someMath.random()
value, my subscription is activated and a returned value is printed when navigating betweenParent <> Child
routes. https://stackblitz.com/edit/angular-ivy-9ajhzu?file=src%2Fapp%2Fmodules%2Fusers.service.tsHave you tried subscribing to the navigation events instead? This should unblock you - https://stackblitz.com/edit/angular-ivy-5wtfjy?file=src%2Fapp%2Fmodules%2Fusers.component.ts
I’m not sure I follow this exactly. Is it shown in the reproduction? I would guess this is unrelated and actually has to do with component reuse or lack thereof.