Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NgRx - Multi level route params not able to access from CustomSerializer Router Store

I have a path declared like:

{
  path: 'app/:userId',
  children: [...AppChildrenRoutes]
}

And then, inside AppChildrenRoutes

{ path: 'feature', component: MainFeatureComponent }

So, at some point of my application I can have localhost:4200/app/123/feature. Inside this component, with some action, I can navigate to another route like this:

this.router.navigate([
  'app',
  this.userId,
  'feature',
  { search: this.searchFor }
]);


Consider it as a big enterprise sized application that is changing architecture, to use NgRx, step by step.
So, I faced a problem with Router Store. I've set up everything and it works.
Following Router Store docs I wrote a Custom Serializer and it looks like this

serialize(routerState: RouterStateSnapshot): RouterStateUrl {
  const { url } = routerState;
  const queryParams = routerState.root.queryParams;

  while (route.firstChild) {
    route = route.firstChild;
  }
  const params = route.params;

  return { url, queryParams, params };
}

And I found out that, considering a URI like

localhost:4200/app/123/feature;search=blue

the route.params returns only the search param, not both userId and search.

- How can I implement a CustomSerializer that returns all params from the path? (in this case, both userId and search).

I kinda tried but failed to, each iteration of the while loop, check if there was a param and add them to a object until the last one. Good, Ok or Bad approach? How could I work that and not fail?
Thanks.

like image 684
João Ghignatti Avatar asked Oct 26 '25 21:10

João Ghignatti


1 Answers

I had a similar problem and solved it by extending the params object every time I go through the loop.

My CustomSerializer now looks like this:

export class CustomSerializer implements RouterStateSerializer<RouterStateUrl> {
serialize(routerState: RouterStateSnapshot): RouterStateUrl {
    let route = routerState.root;

    let params = {};
    while (route.firstChild) {
        params = {
            ...params,
            ...route.params
        };
        route = route.firstChild;
    }

    const {
        url,
        root: { queryParams }
    } = routerState;

    return { url, params, queryParams };
}

}

like image 120
coettl Avatar answered Oct 29 '25 16:10

coettl