me-and-viy
me-and-viy

Reputation: 109

Map Router data with urlAfterRedirects - NavigationEnd url and ActivationEnd snapshot data

I need to map the NavigationEnd url and ActivationEnd snapshot data, in order to get the route date for current route.

I specify router data in data object in routing module. like this:

path: 'assign/:state',
data: { skipBackNavigation: true },
component: OrderAssignComponent

So I need to subscribe to Router Events, that when I navigate to assign/:state - I need to get the data and the current url.

What I did:

const routerData$ = this.router.events.pipe(
  filter(e => e instanceof ActivationEnd),
  map((e: ActivationEnd) => e.snapshot.data)
);

const urlAfterRedirects$ = this.router.events.pipe(
  filter(event => event instanceof NavigationEnd),
  map((navEnd: NavigationEnd) => navEnd.urlAfterRedirects)
);

This brings me following result:

enter image description here

So following thing I need to do: I need to map the NavigationEnd (A) event with the ActivationEnd event which contains the data for current route (1). The problem is that the ActivationEnd event happens before the actual Navigation end, and we need to map only first ActivationEnd event on every NavigationEnd.

I have already tried switchMap - but it takes the NEXT ActivationEnd, in result I get the wrong data mapped:

urlAfterRedirects$
  .pipe(
    tap(url => console.log(url)),
    switchMap((url) => routerData$.pipe(map((data) => ({ url, data }) ))),
  )
  .subscribe(({url, data}) => console.log(url, JSON.stringify(data)));

Please suggest how to map it correctly

Upvotes: 1

Views: 1678

Answers (1)

me-and-viy
me-and-viy

Reputation: 109

I found a solution in this Angular bug report

So basically all that is needed to do is to filter out the ActivationEnd event in this particular way:

const routerData$ = this.router.events
  .pipe(
    filter(event => event instanceof ActivationEnd),
    filter((event: ActivationEnd) => event.snapshot.firstChild === null),
    map((event: ActivationEnd) => event.snapshot.data));

Also I have used withLatestFrom RXJS operator.

urlAfterRedirects$
      .pipe(withLatestFrom(routerData$))

Upvotes: 1

Related Questions