LoginSignup
6
5

More than 5 years have passed since last update.

【Angular7】Guard の返り値に UrlTree を指定する

Last updated at Posted at 2018-11-12

この記事は何?

Angular 7.1 から Guard の 返り値として UrlTree が指定できるようになりました。
このアップデートにより、Guard 内の記述が直感的になったので紹介したいと思います。

現在の最新版は 7.1.0-beta.2 ですが、自分が試す限りは不具合等なく快適に使用できるので時間がある方は是非リファクタしてみてください ( ´ ▽ ` )

Before

サンプルコードは、ほとんどのアプリで使われていそうなログイン状態確認用 Guard にしたいと思います。
/mypage 的なパスへ設定して、ログインしていない場合はログインページへ遷移させる典型的なパターンで使います。

canActivate の返り値は Observable<boolean> | Promise<boolean> | boolean ですが、記述が冗長で読みづらいため使っている型のみ指定しています。

auth.guard.ts
@Injectable()
export class AuthGUard implements CanActivate {
    constructor(private authService: AuthService, private router: Router) {}

    public canActivate(
        next: ActivatedRouteSnapshot,
        state: RouterStateSnapshot,
    ): boolean {
        if (this.authService.isSignIn()) {
            // 認証後専用ページへ遷移
            return true;
        }

        // ログインページへ遷移
        this.router.navigate(['auth/sign-in']);

        // ルーティング中止
        return false;
    }
}

なんというか、ルーティングの流れを一旦止めてるのに別軸で新たな流れを生み出して無理やり遷移している感じがちょっと気持ち悪いなぁと感じていました。

After

auth.guard.ts
@Injectable()
export class AuthGUard implements CanActivate {
    constructor(private authService: AuthService, private router: Router) {}

    public canActivate(
        next: ActivatedRouteSnapshot,
        state: RouterStateSnapshot,
    ): boolean | UrlTree {
        if (this.authService.isSignIn()) {
                        // 認証後専用ページへ遷移
            return true;
        }

-        // ログインページへ遷移
-        this.router.navigate(['auth/sign-in']);
-
-        // ルーティング中止
-        return false;
+        // 現在のルーティングを中止し、ログインページへ遷移
+        return this.router.parseUrl('auth/sign-in');
    }
}

これぞ求めていたもの!って感じです。
非常に明快なコードになりました。

もちろん ObservablePromise 型でも OK なので、場合によって使い分けてください。

can-activate.d.ts
export interface CanActivate {
    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree;
}

おまけ

skipLocationChange 等のオプションを指定している場合は createUrlTree をご利用ください。
(というか、使う or 使わない の判断しなくて良いので全部こっちでいいかも、、、

return this.router.createUrlTree(['auth', 'sign-in'], {
    skipLocationChange: true,
    queryParams: {
        [ReturnUrlParamName]: state.url,
    },
});
6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5