Search code examples
angularangular2-router

Angular router doesn't respond properly for browser url


My problem is when i change the url in the browser it always leads to the start route and when i type something else other than paths that exist in the router i get 404.

app-routing.module.ts

const routes: Routes = [
  {path: "start", canActivate:[RoutingGuard], component: Start},
  {path: "path-1", canActivate:[RoutingGuard], component: One},
  {path: "path-2", canActivate:[RoutingGuard], component: Two},
  {path: "path-3", canActivate:[RoutingGuard], component: Three},
  {path: "path-4", canActivate:[RoutingGuard], component: Four},
  {path: "", component: Public},
  {path: "**", redirectTo: "", pathMatch:'full'}
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})

routing-guard.service.ts:

canActivate() {
        this._mysvc.isAuthorized().subscribe(data => this.auth = data);
        if (!this.auth) {
            this._router.navigate(['/']);
        }
        return this.auth;
    }

I have a login and in Public component i have this method that redirects to /start if the user is logged in.

public.component.ts:

    isAuthorized(authorized:boolean):void {
        if (authorized) {
          this._router.navigate(['/start']);
        }
      }
  ngOnInit():void {
    this._mysvc.isAuthorized().subscribe(this.isAuthorized.bind(this), this.isAuthorizedError);
  }

index.html:

<html lang="en">
<head>
  <base href="/">

  <!--<meta charset="UTF-8">-->
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
  <app-root></app-root>
</body>
</html>

I use rewrite config so i skip the # in the url

rewrite.config:

RewriteRule /start/? /index.html [NC]
RewriteRule /path-1/? /index.html [NC]
RewriteRule /path-2/? /index.html [NC]
RewriteRule /path-3/? /index.html [NC]
RewriteRule /path-4/? /index.html [NC]

Solution

  • The problem is async request which you handle as being sync:

    canActivate(): Observable<boolean> {
      return this._mysvc.isAuthorized().do((auth: boolean) => {
         if (!auth) {
           this._router.navigate(['/']);
         }
      });
    }
    

    For this you need to import the do operator:

    import 'rxjs/add/operator/do'
    

    Or:

    async canActivate(): Promise<boolean> {
      if (!await this._mysvc.isAuthorized().toPromise()) {
         this._router.navigate(['/']);
      }
      return auth;
    }
    

    for this you need to import the toPromise operator

    import 'rxjs/add/operator/toPromise';