13

I'm finding that router.isActive is returning false any time a secondary route is open.

Is router.isActive suitable for checking 'am I on route (x)?' (e.g.: payments page) - regardless of hashstates, query params and secondary routes.

Should router.isActive be the right service/call to deduce this? Or is it intended for something simpler. Is there an alternative? Should write my own service?

E.g.:

  • When on /second, router.isActive('second', true) === true
    • (good)
  • When on second(modal:my-modal), router.isActive('second', true) === false
    • The issue: This function is now no longer useful to determine if I'm on the second page
  • When on /second, router.isActive('', false) === true. (non-exact matches return true parent/child states

I've created a plnkr proof of concept, for easier testing:

enter image description here

Overflew
  • 7,872
  • 10
  • 45
  • 65
  • you are on "/second(popup:global-popup)" url. so what isActive('/second', true) should return true? probably isActive('/second(popup:global-popup)', true) will return true. – Julia Passynkova Apr 27 '17 at 13:11
  • Thanks. What I'm looking for is a "am I on this page?" function, which will ignore secondary routes, querystring params, hashstates, or any other non-primary (route) page identifier. – Overflew Apr 27 '17 at 21:29
  • 1
    Funny! I'm having the opposite problem. I get `router.isActive(...) == true` for ANY value. eg. `router.isActive('blah', 'does', 'not', exist') is true` – Simon_Weaver Nov 30 '19 at 21:39

1 Answers1

5

Taking a look at the source here:

https://github.com/angular/angular/blob/master/packages/router/src/router.ts#L493

So you specify a urlTree or a string, and whether an exact match is necessary.

Lets take a look at what it does after that.

return containsTree(this.currentUrlTree, urlTree, exact);

So lets look at containsTree.

https://github.com/angular/angular/blob/master/packages/router/src/url_tree.ts#L16

Looks like it does an exact comparison vs. a contains against the tree depending on the value of exact.

A bit more investigation leads us here:

export function shallowEqual(a: {[x: string]: any}, b: {[x: string]: any}): boolean {
  const k1 = Object.keys(a);
  const k2 = Object.keys(b);
  if (k1.length != k2.length) {
    return false;
  }
  let key: string;
  for (let i = 0; i < k1.length; i++) {
    key = k1[i];
    if (a[key] !== b[key]) {
      return false;
    }
  }


 return true;
}

So it looks like the urlTree comparisons are done using a 'generic' shallow comparison algorithm to determine exactness. That makes me think that the current isActive() method is not robust enough (or was intentionally designed that way) to make determinations at the level of granularity you need.

I'm not certain if there is a better way (other than maybe parsing it yourself), or if this is intentional for the isActive() method. I would guess that the isActive() method (when using exactness) was probably written this way because the term exact implies that even having the secondary route does not yield an exact match.

It's probably worth a discussion with the Angular guys to see if there is a way you can get a hook to that information.

chrispy
  • 3,552
  • 1
  • 11
  • 19
  • 1
    Thanks. I found this issue on GitHub, which covers some wider shortcomings with isActive: https://github.com/angular/angular/issues/13205 . – Overflew May 10 '17 at 21:46
  • Good catch -- sounds like something that they've already noted and will hopefully address soon. – chrispy May 10 '17 at 23:01