Tag Archives: how-it-works-angular

How it works: Angular Routes

Angular routes allows you to setup how your components are going to show up in the page.

Routes can be guarded (like require a login to access) and they can be nested (you can have components render components in a specific route).

Routes can also be setup as lazy, they will only load the component when needed. And you can delegate the loading to sub modules.

“Full” setup

You can check a “full” setup in this plnkr example – setting up Angular routes with lazy load and child routes.

The basics

export const routes: Routes = [
  // if it hits root then go to fooroute
  { path: '', redirectTo: 'fooroute', pathMatch: 'full' },

  // if it hits this route then render FooComponent
  { path: 'fooroute', component: FooComponent },

  // if no routes were found falls into this one that renders Notfound
  { path: '**', component: NotfoundComponent },
];

Route with parameters

You can use :name to declare parameters in your route.

{ path: 'heroes/:id', component: HeroesComponent },

To create links passing parameters you can pass an array with the route and all parameters, like this:

<a [routerLink]="['heroes', 1]">Saitama</a>

To access the parameters you need private route: ActivatedRoute on your constructor to get route information, and you need to implement OnInit and OnDestroy.

import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({...})
export class HeroesComponent implements OnInit, OnDestroy {
  id: any;
  sub: any;

  constructor(private route: ActivatedRoute) {
  }

  ngOnInit() {
    this.sub = this.route.params.subscribe((params) => {
      this.id = +params['id'];
    });
  }

  ngOnDestroy() {
    this.sub.unsubscribe();
  }
}

Route with guard

A guard is a class that implements CanActivate or CanActivateChild. In a single route (as the examples above) you might want to use CanActivate, but when you have child routes you might want to use CanActivateChild (for example in /admin routes protecting everything inside it).

Both interfaces are do the samething, they have a method that returns true or false and can redirect you to another page (ex: login page).

An example that could be used to protect an admin area, only allow access if the user is logged in.

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

import { Injectable } from '@angular/core';

@Injectable()
export class AuthGuard implements CanActivateChild {
  constructor(private router: Router) { }

  canActivateChild() {
    if (localStorage.getItem('user')) {
      return true;
    }

    this.router.navigate(['/login']);
    return false;
  }
}

Route with lazy and children

import { RouterModule, Routes } from '@angular/router';

import { AuthGuard } from 'src/auth.guard'; // see previous example
import { ModuleWithProviders } from '@angular/core';

import { InternalComponent } from 'src/layouts/internal.component';
import { PublicComponent } from 'src/layouts/public.component';

export const routes: Routes = [
  { path: '', redirectTo: 'heroes', pathMatch: 'full' },

  {
    path: '',
    canActivateChild: [AuthGuard], // protects all heroes routes
    component: InternalComponent,
    children: [
      { path: 'heroes', loadChildren: 'src/heroes/heroes.module#HeroesModule' },
    ],
  },

  {
    path: '',
    component: PublicComponent,
    children: [
      { path: 'login', loadChildren: 'src/login/login.module#LoginModule' },
      // { path: 'error', loadChildren: 'src/error/error.module#ErrorModule' },
    ],
  },

  // { path: '**', redirectTo: 'error' },
];

export const router: ModuleWithProviders = RouterModule.forRoot(routes);

Module setup

In app.module

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

In sub modules (if lazy loading)

@NgModule({
  imports: [ RouterModule.forChild(routes) ],

If I’m missing a piece of configuration here, then check the plnkr example – setting up Angular routes with lazy load and child routes which is working and you can complete the error route for practice. 🙂

How it works: Angular Tests

Angular tests are always in the same place as the code. When you create a component, service, pipe, directive with ng generate it will always also generate a .spec.ts file.

Every file with the extension .spec.ts is a test file that is caught by the testing tool. Each thing is tested in a different way. For a really long documentation on tests check the official documentation here.

Continue reading

How it works: Angular Pipes

Angular pipes are functions that transform values. There are some built-in pipes and you can create your own pipes.

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'required' })
export class RequiredPipe implements PipeTransform {
  transform(value: string, ...args: any[]) {
    return `The field ${value} is required.`;
  }
}

Continue reading

How it works: Angular Components

Angular components are elements composed by a template that will render your application.

import { Component } from '@angular/core';

@Component({
  providers: [],
  selector: 'app-required',
  styleUrls: ['required.component.scss'],
  // template: `This field is required.`,
  templateUrl: 'required.component.html',
})
export class RequiredComponent { }

Continue reading

How it works: Angular Modules

Angular modules are containers for different parts of your app.

You can have nested modules, your app.module is already actually nesting other modules such as BrowserModule and you can add RouterModule and so on.

A module is a class with the @NgModule decorator

import { AppComponent } from './app.component';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

@NgModule({
  bootstrap: [AppComponent]
  declarations: [AppComponent],
  exports: [],
  imports: [BrowserModule],
  providers: [],
})
export class AppModule { }

Continue reading