angular: RouteLink annotation throws an exception

From @ElsewhereGames on June 20, 2016 16:11

Tried to switch from the deprecated router to alpha 7 of this one, but I am not able to use routeLinks in on my child routes. I have a list of routes like this:

<a [routerLink]="['inputs']">Inputs</a>
<a [routerLink]="['outputs']">Test</a>

When I first open the page with these links, none of them appear to be clickable (in other words, no hand cursor on mouse-over). When I do click any of the links, the console shows an error:

Uncaught EXCEPTION: Error in ./NavigationLinkComponent class NavigationLinkComponent - inline template:0:0
ORIGINAL EXCEPTION: TypeError: Cannot read property 'length' of undefined
ORIGINAL STACKTRACE:
TypeError: Cannot read property 'length' of undefined
    at UrlParser.parseSegmentChildren (http://127.0.0.1:8181/scripts/vendors.js:76681:28)
    at UrlParser.parseRootSegment (http://127.0.0.1:8181/scripts/vendors.js:76677:56)
    at DefaultUrlSerializer.parse (http://127.0.0.1:8181/scripts/vendors.js:76554:42)
    at Router.navigateByUrl (http://127.0.0.1:8181/scripts/vendors.js:75894:47)
    at RouterLink.onClick (http://127.0.0.1:8181/scripts/vendors.js:75718:22)
    at DebugAppView._View_NavigationLinkComponent0._handle_click_0_0 (NavigationLinkComponent.template.js:67:36)
    at http://127.0.0.1:8181/scripts/vendors.js:41217:25
    at http://127.0.0.1:8181/scripts/vendors.js:66297:37
    at http://127.0.0.1:8181/scripts/vendors.js:67190:112
    at ZoneDelegate.invoke (http://127.0.0.1:8181/scripts/vendors.js:19012:30)

My source maps point me to this line:

if (this.remaining.length == 0) {
  return {};
}

I looked around for a demo project or starting plunker, but I was not able to find one yet (the documentation uses alpha 3). Any help is appreciated!

Copied from original issue: angular/vladivostok#91

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 27 (11 by maintainers)

Most upvoted comments

@zacharyclaysmith I’m seeing the same error:

browser_adapter.ts:82 TypeError: Cannot read property 'startsWith' of undefined
    at UrlParser.parseRootSegment (url_tree.ts:301)
    at DefaultUrlSerializer.parse (url_tree.ts:196)
    at Router.navigateByUrl (router.ts:242)
    at RouterLinkWithHref.onClick (router_link.ts:87)
    at DebugAppView._View_GetStartedComponent0._handle_click_68_0 (GetStartedComponent.template.js:335)
    at view.ts:406
    at dom_renderer.ts:274
    at dom_events.ts:20
    at ZoneDelegate.invoke (zone.js:323)
    at Object.onInvoke (ng_zone_impl.ts:72)
{
  "@angular/common": "2.0.0-rc.4",
  "@angular/compiler": "2.0.0-rc.4",
  "@angular/core": "2.0.0-rc.4",
  "@angular/forms": "^0.2.0",
  "@angular/http": "2.0.0-rc.4",
  "@angular/platform-browser": "2.0.0-rc.4",
  "@angular/platform-browser-dynamic": "2.0.0-rc.4",
  "@angular/router": "3.0.0-beta.2",
  "@angular/upgrade": "2.0.0-rc.4"
}

Some investigation:

// @angular/router/src/directives/router_link.ts

export class RouterLinkWithHref implements OnChanges {
  /* ... */
  urlTree: UrlTree;
  /* ... */
  ngOnChanges(changes: {}): any { this.updateTargetUrlAndHref(); }
  onClick(button: number, ctrlKey: boolean, metaKey: boolean): boolean {
    if (button !== 0 || ctrlKey || metaKey) {
      return true;
    }

    if (typeof this.target === 'string' && this.target != '_self') {
      return true;
    }

    this.router.navigateByUrl(this.urlTree); // this.urlTree = undefined
    return false;
  }
}
// @angular/router/src/router.ts
class Router {
  /* ... */
  navigateByUrl(url: string|UrlTree): Promise<boolean> { // url = undefined
    if (url instanceof UrlTree) {
      return this.scheduleNavigation(url, false);
    } else {
      const urlTree = this.urlSerializer.parse(url);
      return this.scheduleNavigation(urlTree, false);
    }
  }
  /* ... */
}

RouterLinkWithHref updates its urlTree property when ngOnChanges() fires, but that isn’t happening before onClick() fires so we end up being unable to schedule navigation properly.

@artuska https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith Support of String.prototype.startsWith started in Safari 9. So you simply need some sort of polyfill RTM: https://angular.io/guide/browser-support#polyfill-libs

@robwormald I’m also getting a very similar error when trying to use routeLink. Not sure of the current status of this issue. Here’s the error as output in the browser:

ORIGINAL EXCEPTION: TypeError: Cannot read property 'startsWith' of undefined ORIGINAL STACKTRACE: TypeError: Cannot read property 'startsWith' of undefined at UrlParser.parseRootSegment (eval at <anonymous> (http://localhost:3000/vendor.bundle.js:1743:2), <anonymous>:303:27) at DefaultUrlSerializer.parse (eval at <anonymous> (http://localhost:3000/vendor.bundle.js:1743:2), <anonymous>:200:30) at Router.navigateByUrl (eval at <anonymous> (http://localhost:3000/vendor.bundle.js:1545:2), <anonymous>:243:46) at RouterLinkWithHref.onClick (eval at <anonymous> (http://localhost:3000/vendor.bundle.js:1539:2), <anonymous>:89:21) at DebugAppView._View_LeftNavComponent0._handle_click_10_0 (LeftNavComponent.template.js:504:45) at eval (eval at <anonymous> (http://localhost:3000/vendor.bundle.js:674:2), <anonymous>:375:24) at eval (eval at <anonymous> (http://localhost:3000/vendor.bundle.js:1333:2), <anonymous>:254:36) at eval (eval at <anonymous> (http://localhost:3000/vendor.bundle.js:1345:2), <anonymous>:27:111) at ZoneDelegate.invoke (eval at <anonymous> (http://localhost:3000/polyfills.bundle.js:2671:2), <anonymous>:323:29) at Object.onInvoke (eval at <anonymous> (http://localhost:3000/vendor.bundle.js:500:2), <anonymous>:53:41)

I’m using webpack, and get this for any/all routeLinks used within templates that are nested within a parent <router-outlet>. Let me know what other info you need. For now, I’m doing a work-around using click events and manual routing.

I just did a quick test, and this tag “works” on a root level template: <a [routerLink]="['/hello']">hello</a>

but breaks with the above error on child templates (i.e. templates rendered within a router-outlet component).

*Snippet of current Angular dependencies from package.json: “@angular/common”: “2.0.0-rc.4”, “@angular/compiler”: “2.0.0-rc.4”, “@angular/core”: “2.0.0-rc.4”, “@angular/forms”: “^0.2.0”, “@angular/http”: “2.0.0-rc.4”, “@angular/platform-browser”: “2.0.0-rc.4”, “@angular/platform-browser-dynamic”: “2.0.0-rc.4”, “@angular/router”: “3.0.0-beta.2”, “@angular/upgrade”: “2.0.0-rc.4”,

Update: When I remove most of the code from my app, I basically end up with the following:

  • A routerLink outside of a <router-outlet> works fine.
  • A routerLink inside of a <router-outlet> doesn’t seem to get processed.

What I mean by this is that the link in the outlet does not the ng-reflect-router-link or ng-reflect-href attributes assigned.

image

I still am not able to reproduce this behavior with a plunkr.