Skip to content Skip to sidebar Skip to footer

Angular 4 - Routerlinks Without Starting Slash Get Rewritten After Uncaught Error

This is a follow up to Angular 4 + zonejs: routing stops working after uncaught error since we had a hard time integration the suggested changes into our project. The reason for th

Solution 1:

After an navigation error happens the routing state is restored

this.currentRouterState = storedState;this.currentUrlTree = storedUrl;

https://github.com/angular/angular/blob/4.1.2/packages/router/src/router.ts#L750-L751

After that within executing createUrlTree the startPosition is obtained:

functionfindStartingPosition(nav, tree, route) {
    if (nav.isAbsolute) { // it will be executed when you use `/` in routeLinkreturnnewPosition(tree.root, true, 0);
    }
    if (route.snapshot._lastPathIndex === -1) { // without '/'returnnewPosition(route.snapshot._urlSegment, true, 0);
    }
    ...
}

As we can see in code above when you use slash in routeLinks then router will create position based on tree.root which has not changed.

then it is used for creating UrlTree (oldSegmentGroup in code below)

function tree(oldSegmentGroup, newSegmentGroup, urlTree, queryParams, fragment) {
    ...
    if (urlTree.root === oldSegmentGroup) { // will be false after the error
        return new UrlTree(newSegmentGroup, qp, fragment);
    }
    return new UrlTree(replaceSegment(urlTree.root, oldSegmentGroup, newSegmentGroup), qp, fragment);
}

So workaround might be as follows:

We no longer need RouteReuseStrategy.

We store errored state

let erroredUrlTree;
let erroredState;

exportclassAppModule {
  constructor(private router: Router) {
    router.events.subscribe(function (e) {
      if(e instanceofNavigationError ) {
        erroredState = (router asany).currentRouterState;
        erroredUrlTree =  (router asany).currentUrlTree;
      }
    });
  }
}

and recovery it after error occurs:

@Injectable()
exportclassMyErrorHandlerimplementsErrorHandler {
  constructor(private inj: Injector) {}

  handleError(error: any): void {
    console.log('MyErrorHandler: ' + error);
    if(erroredUrlTree) {
      letrouter: any = this.inj.get(Router);
      router.currentRouterState = erroredState;
      router.currentUrlTree = erroredUrlTree;
      erroredState = null;
      erroredUrlTree = null;
    }
  }
}

Modified Plunker

It looks terrible but maybe it will help to understand what the problem is

Post a Comment for "Angular 4 - Routerlinks Without Starting Slash Get Rewritten After Uncaught Error"