0

When I manually try to open certain page (by typing url in browser) seems like my app can't find what route to use. Page is loading but router-outlet is empty. Also I receive "EmptyError: no elements in sequence". Found that this is some troubles with canActivate method, tried to change Observables to Promise as it says here EmptyError: no elements in sequence but still get error.

My app also have custom base href, defined in index.html

app.routing.ts

const appRoutes: Routes = [
    {
        path: 'project',
        canActivate: [AuthGuard],
        canActivateChild: [AuthGuard],
        children: [
            {
                path: 'home',
                component: HomeComponent
            },
            {
                path: 'events',
                loadChildren: 'app/feature/events/events.module#EventsModule'
            },
        ],
    }
];

So when I try to go "localhost/some/base/href/project/home" I get empty page, only app's main menu visible. Also, url became "localhost/some/base/href" Then I can navigate my app by clicking buttons on app's main menu (theirs hyperlinks are 'localhost/some/base/href/project/events/list' for example). This work perfect, routes founded.

Tried to change path in appRoutes to 'some/base/href/project' and now when I go to "localhost/some/base/href/project/home" HomeCompoment is loaded but url became "localhost/some/base/href/some/base/href/project/home" and also buttons on app's main menu stop working.

Of course, I can make redirect

path: '**',
redirectTo: '/project/home',
pathMatch: 'full'

But this will get me only homepage, I want to manually navigate to other components in app.

UPDATE: My authGuard, also tried return Observable and Promise but no effect. isAuthorized() always return true now.

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        let result: boolean = this.authService.isAuthorized();

        if (result) {
            return true;
        }

        this.authService.setRedirectUrl(state.url);

        return false;
    }
Ethan
  • 13
  • 2
  • 6
  • can you show how implemented the guard? – Rohit Ramname Dec 01 '17 at 15:36
  • @RRForUI edited – Ethan Dec 04 '17 at 08:25
  • if you are hosting your application in IIS in virtual directory, try keeping href tag empty. That may be able to keep your URLs correct. Also, if you using service to return value for guards, make it return observable, canActivate should automatically subscribe to the guard. – Rohit Ramname Dec 04 '17 at 16:13

1 Answers1

0

Make your routes this way:

Here we have main branches - Login and Root with empty key - path: ''

And child branches, these path contains children pages - alerts, dashboards and so on.

You able to build path as deep as you need recursively, using children field.

If you want to manually navigate to routes you need to define all paths in you appRoutes array, in the offered style.

const appRoutes: Routes = [
  {path: 'login', component: LoginComponent},
  {path: '', component: MainComponent, redirectTo: '/dashboard', pathMatch: 'full'
    children: [
      { path: 'alert/:id', component: AlertDetailComponent },
      { path: 'alerts', component: AlertsComponent },
      { path: 'dashboard', component: EriskDashboardComponent }
  ]}];

And you able to make some default route to login / 404 page

path: '**',
redirectTo: '/login',
pathMatch: 'full'

Additionally, need to mention, that angular router uses hash symbol by default in router - #;

So to navigate to login you need to build path like this:

#/login
#/dashboard

http://localhost:4200/#/login

Setting to use hash can be found in app.module.ts, when we importing router module:

imports:[
    RouterModule.forRoot(routes, { useHash: true }),
]
Alexander K
  • 101
  • 1