1

I am currently developing an angular app using its router functionality. All routes seem to have been working well until I found out that after a successful login, the url path I've set it to, which is '/admin' will not be followed and the router instead defaults to a '/'. This is the code:

//login.component.ts
if (this.authService.getUserRole() == 'user' || 'agent') {
window.location.assign('/')
} else if (this.authService.getUserRole() == 'admin') {
window.location.assign('/admin')
}



//app.routing.ts
import {AdminComponent} from './admin-master/admin/admin.component;
import {HomeComponent} from './home/home.component;

const appRoutes: Routes = [
{path: '', component: HomeComponent, pathMatch: 'full'},
{path: 'admin', component: AdminComponent, canActivate: [AuthGuard], data: {permission:{only: ['admin']}}}
]

EDIT: (added auth.guard.ts)

//auth.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service';

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {
  constructor(private authService: AuthService, private router: Router) {}

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {

      const permission = next.data["permission"];

      if(this.authService.isLoggedIn() &&
      permission.only.includes(this.authService.getUserRole())) {
        return true;
      } else {
        this.router.navigateByUrl('/logout');
      }
    
  }
  
}

The Problem:

  1. Although a successful login has been done, the router will redirect a user to a blank url instead of the set URL I have provided specifically in the login.component.ts folder.

  2. Because it will redirect to an empty URL, elements from the home.component.html will also display within my admin dashboard which I don't want to happen.

In conclusion, how do I route the following functions correctly? Am I doing something wrong? Thanks for the help!

6
  • What do you see in your browser console (<kbd>F12</kbd>) Commented Jul 20, 2020 at 18:18
  • @Pieterjan This is what immediately shows in my Router event: Navigation Start:NavigationStart(id: 1, url: '/') Commented Jul 20, 2020 at 18:24
  • What your AuthGuard looks like ? Also your routing looks a little strange to me, you're not using the angular build in routing functionality (angular.io/guide/router) Instead of window.location.assign('/admin') you should use this.router.navigate(['admin'], { relativeTo: this.route }); Commented Jul 20, 2020 at 18:24
  • I'll edit my post to add the AuthGuard! Also, the reason I used window.location.assign is to trick the browser into thinking that I've already redirected to the route. This is due to some of my functionalities only loading if I refresh the application. Commented Jul 20, 2020 at 18:32
  • @Pieterjan any ideas? Commented Jul 20, 2020 at 18:48

4 Answers 4

1

You can use Router instead of window.location.assign to navigate into different URL's

Example:

import { Router} from '@angular/router';

/* Login Component */

constructor(private router: Router, private authService: AuthService) { }

navigate() {
    if (this.authService.getUserRole() == 'user' || 'agent') {
        this.router.navigateByUrl('/')
    } else if (this.authService.getUserRole() == 'admin') {
        this.router.navigateByUrl('/admin')
    }
}

check the doc https://angular.io/api/router/Router

Sign up to request clarification or add additional context in comments.

2 Comments

I've tried this before, but it still does not navigate to my desired route although the login has been successful. The reason why I used window.location.assign is to trick the browser to and to load the new components that I navigated to.
This is the code you should be able to use. I'm very much under the impression that the URL you want to navigate to does not exist. Normally you would get an error in the browser console with more information.
0

Replace window.location.assign('/admin')

with

this.router.navigate([‘../admin’], {relativeTo: this.route});

router : Router route : ActivatedRoute

I hope this is what you want.

2 Comments

can you provide how you added the router to the constructor? Can't seem to replicate your solution.
Inject Router just like u do activatedRoute
0

Are you sure you are navigating to the admin page ? Your code looks wrong I think.

if (this.authService.getUserRole() == 'user' || 'agent') {
    window.location.assign('/')
} else if (this.authService.getUserRole() == 'admin') {
    window.location.assign('/admin')
}

it should be like below otherwise the first one is always true because of || 'agent'

const role = this.authService.getUserRole();
if (role  === 'user' || role === 'agent') {
    window.location.assign('/')
} else if (role  === 'admin') {
    window.location.assign('/admin')
}

also I prefer === for value and type checking.

1 Comment

thank you for pointing out one of my mistakes. || role === 'agent' should've been the right code. Nevertheless, I have found the answer to my problem. I'll post an answer soon!
0

In my app.routing.ts file, I've observed that from the code below, removing {useHash: true} would result in a correct URL redirect. This is due to the fact that adding {useHash: true} adds an extra /# to my url resulting in defaulting to a blank URL because it does not match any routes.

export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes, { useHash: true, enableTracing: true });

I've modified it instead to:

export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);

NOTE: I've also removed enableTracing: true just to clean up my console results.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.