Skip to content

Instantly share code, notes, and snippets.

@adrianlemess
Last active December 27, 2019 17:42
Show Gist options
  • Save adrianlemess/0193b63bede199c0b6c6dac41535b645 to your computer and use it in GitHub Desktop.
Save adrianlemess/0193b63bede199c0b6c6dac41535b645 to your computer and use it in GitHub Desktop.
Angular Awesome List

Core Concepts

Architecture

CORs

TypeScript

Sharing state between components

Diretivas

Tests:

Best Practices

Angular Template

Observables

CSS Specifity

Binding

Import wasm

Form

Web workers

Jest + Angular https://www.xfive.co/blog/testing-angular-faster-jest/ https://www.youtube.com/watch?v=AYBHKoiozhg https://www.youtube.com/watch?v=d91uDEmbBUs https://www.xfive.co/blog/testing-angular-faster-jest/ https://github.com/malaga-front-end/nrwl-angular-jest-cypress-quickstart/tree/master/tutorial/chapter-4-unit-and-snapshot-testing-with-jest https://github.com/goldbergyoni/javascript-testing-best-practices https://netbasal.com/spectator-v4-a-powerful-tool-to-simplify-your-angular-tests-bd65a0bf317e

Shallow render futuro https://medium.com/@getsaf/testing-angular-components-with-shallow-render-9334d16dc2e3

Snippets

Component:

  • HTML
<div *ngIf="item.length > 0">
  <div *ngFor="let item of items">{{ item.name }}</div>
</div>
  • Component.ts
import { Component, OnInit } from '@angular/core';
import { TestService } from '../test-service';

@Component({
  selector: 'app-items',
  templateUrl: './items.component.html',
  styleUrls: ['./items.component.scss']
})

export class ItemsComponent implements OnInit {
  public items: string[] = [];

  constructor(private testService: TestService) {
  }

  ngOnInit() {
  
  }

}

Service

// src/app/auth/auth.service.ts
import { Injectable } from '@angular/core';
import decode from 'jwt-decode';

@Injectable({provideIn: 'root'})
export class AuthService {  

  public getToken(): string {
    return localStorage.getItem('token');
  }  
  
  public isAuthenticated(): boolean {
    // get the token
    const token = this.getToken();
    // return a boolean reflecting 
    // whether or not the token is expired
    return tokenNotExpired(null, token);
  }
 }

Interceptor

// src/app/auth/token.interceptor.ts

import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor
} from '@angular/common/http';
import { AuthService } from './auth/auth.service';
import { Observable } from 'rxjs/Observable';

@Injectable({ provideIn: 'root' })
export class TokenInterceptor implements HttpInterceptor {  

constructor(public auth: AuthService) {}  

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    
    request = request.clone({
      setHeaders: {
        Authorization: `Bearer ${this.auth.getToken()}`
      }
    });    return next.handle(request);
  }
}

Use Interceptor

import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { TokenInterceptor } from './../auth/token.interceptor';

@NgModule({
  bootstrap: [AppComponent],
  imports: [...],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: TokenInterceptor,
      multi: true
    }
  ]
})
export class AppModule {}

Guard

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } 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 {
      if (!this.authService.isAuthenticated()) {
        this.router.navigate(['/login']);
      } 

      return this.authService.isAuthenticated();
  }

  canActivateChild(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot) {
      return this.canActivate(next, state);
    }
  
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment