---
title: "Cleanse your Angular components of Route specific code"
description: "Cleanse your Angular components of Route specific code"
published: "2018-03-23"
last_updated: "2018-03-23"
authors:
  - "David East (Developer Advocate)"
categories:
  - "Angular"
  - "AngularFire"
  - "Best Practices"
canonical_url: "https://firebase.blog/posts/2018/03/cleanse-your-angular-components"
---

# Cleanse your Angular components of Route specific code

*Published March 23, 2018 by David East (Developer Advocate)*

---
All too often I become frustrated when building an authentication component. The asynchronous flow is hard to manage and it makes my template a mess of ngIfs and Elvis operators:

```js
{{ (user | async)?.uid }} 
```

The problem is always same. I'm mixing too many concerns in one place. Organizing the right code in the right place is what makes a happy codebase.

**The solution**: Store route specific code in Angular's Route Guards.

### Route Guards

#### 1. Identify Route code in your component 
The `AngularFireAuth` service is a great match for routing code. It contains information about a current user, whether they are coming from a redirect, and all sorts of other things.

Take a simple `signInWithRedirect` example:

```js
import { Component, OnInit } from '@angular/core';
import { AngularFireAuth } from 'angularfire2/auth';
import { Router } from '@angular/router';
import * as firebase from 'firebase/app';

@Component({
  selector: 'app-login',
  template: `
    <button class="btn" (click)="auth()">
       Login
    </button>
  `,
  styleUrls: ['./login.scss']
})
export class LoginComponent implements OnInit {

  constructor(
    private afAuth: AngularFireAuth,
    private router: Router
  ) { }

  ngOnInit() {
    this.afAuth.getRedirectResult().then(result => {
      if(result) {
        this.router.navigateByUrl('profile');
      }
    });
  }

  auth() {
    const provider = new firebase.auth.GoogleAuthProvider();
    this.afAuth.auth.signInWithRedirect(provider); 
  }

} 
```

Here's what's going in this example:

1.  The user is logged in with the `auth()` method.
2.  The `signInWithRedirect()` method triggers a redirect to sign in with Google.
3.  After the user selects their account, they are taken back to this component.
4.  The `getRedirectResult()` promise in `ngOnInit()` resolves the logged in user.
5.  The router navigates the user to the profile page via the `navigateByUrl()` method.

This isn't a problem with one component. However, imagine having to manage redirects in multiple components.

The code in `ngOnInit` belongs in a Route Guard. This will clean up the component of routing logic and remove the `Router` dependency entirely.

#### 2. Create a Route Guard 
A Route Guard is used for all sorts of useful things. In this case a guard can handle the redirect code.

```js
@Injectable()
export class RedirectGuard implements CanActivate {

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

  canActivate() {
    this.authService.auth.getRedirectResult().then(result => {
      if(result.user != null) {
        this.router.navigateByUrl('profile');
        return false;
      }
      return true;
    });
  }

} 
```

The `canActivate` method determined if the user has access to the route. Here's what happens:

1.  The user visits the route.
2.  `AngularFireAuth` checks if a redirect result exists.
3.  If a user comes back from a redirect, route to the `'profile'` route.
4.  Else, go to the current route.

#### 3. Set up the route
This code is now reusable. The Angular Router lets you specify which routes you want to listen for a redirect.

```js
import { Routes, RouterModule } from '@angular/router';
import { LoginComponent } from './login/login.component';
import { RedirectGuard } from './redirect.guard';

const ROUTES: Routes = [
  { 
    path: '', 
    component: LoginComponent, 
    canActivate: [RedirectGuard] 
  },
  { 
    path: 'profile', 
    loadChildren: 'app/profile/profile.module#ProfileModule'
  }
];

const AppRoutes = RouterModule.forRoot(ROUTES);

export { AppRoutes } 
```

#### 4. No more routing code in the component
Now the `LoginComponent` is free of routing code:

```js
@Component({
  selector: 'app-login',
  template: `
     <button class="btn" (click)="auth()">
       Login
     </button>
  `,
  styleUrls: ['./login.scss']
})
export class LoginComponent {

  constructor(private afAuth: AngularFireAuth) { }

  auth() {
    const provider = new firebase.auth.GoogleAuthProvider();
    this.afAuth.auth.signInWithRedirect(provider); 
  }

} 
```

No more async flow mess. The right code is organized in the right place. You can add the `RedirectGuard` to more routes as the app grows, which keeps the complexity out of your components.
