Reputation: 4538
I have this routing set up:
const SONGS_ROUTES = [
{
path: "songs",
children: [
// ...
{
path: "edit/:id",
component: PerformancesComponent, // CHILD ROUTE
},
{
path: "",
component: PerformancesComponent,
},
],
},
];
const routes: Routes = [
{
path: "",
component: ConcertsComponent,
children: [
{
path: "edit/:friendlyUrl",
component: ConcertEditComponent, // PARENT route
children: SONGS_ROUTES,
},
],
},
];
and I need to be able to get friendlyUrl
with ngrx selectors in every component in the tree. So I defined it as follows:
export const routerFeatureKey = "router";
export const selectRouterState = createFeatureSelector<
fromRouter.RouterReducerState
>(routerFeatureKey);
export const {
selectCurrentRoute, // select the current route
selectQueryParams, // select the current route query params
selectQueryParam, // factory function to select a query param
selectRouteParams, // select the current route params
selectRouteParam, // factory function to select a route param
selectRouteData, // select the current route data
selectUrl, // select the current url
} = fromRouter.getSelectors(selectRouterState);
export const getSelectedConcertFriendlyUrl = selectRouteParam("friendlyUrl");
It does work at the "PARENT" level component (route). Which means when a user goes to edit/some-concert
the selector returns some-concert. But for the /edit/some-concert/edit/songs/1
(in the child component) it returns undefined
. And I have no idea why.
I tried both routerState: RouterState.Minimal
and routerState: RouterState.Full
. Same result.
What new things can I try?
Upvotes: 5
Views: 2742
Reputation: 114
For those crawling the net for a solution to this, I found an alternative to writing a custom selector on another SO thread.
in app-routing.module.ts
@NgModule({
imports: [RouterModule.forRoot(routes, {
paramsInheritanceStrategy: 'always' <---- the important part
})],
exports: [RouterModule]
})
Original answer that solved the question: https://stackoverflow.com/a/51817329/5775417
Upvotes: 9
Reputation: 4538
To workaround this I created my own selector:
export const getSelectedConcertFriendlyUrl = createSelector(
selectUrl,
(url) => {
const extractRegex = /\/concerts\/edit\/([a-zA-Z0-9_-]+)\/?.*/gi;
const matches = extractRegex.exec(url);
if (matches && matches.length > 1 && matches[1]) {
return matches[1];
}
return undefined;
}
);
It's doesn't include all edge cases for now, so I'll have improve it.
And then @brandonroberts kindly replied on Twitter that:
The selectors for router-store traverse down to the lowest active route in the tree, which is why you won't get that parameter. If you need to all the params in the tree, you need a custom selector.
So yes, you have to create your own selector.
Upvotes: 0