Skip to content

Instantly share code, notes, and snippets.

@gopalakrishnan-subramani
Last active March 1, 2020 10:16
Show Gist options
  • Save gopalakrishnan-subramani/714aab26b87f2e79a87905f241ada11c to your computer and use it in GitHub Desktop.
Save gopalakrishnan-subramani/714aab26b87f2e79a87905f241ada11c to your computer and use it in GitHub Desktop.
Angular
import { Component, OnInit } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
@Component({
selector: 'app-about',
templateUrl: './about.component.html',
styleUrls: ['./about.component.scss']
})
export class AboutComponent implements OnInit {
html=`<div>
<h1>Angular Router</h1>
</div>`;
safeHtml: any;
constructor(private sanitizer:DomSanitizer) { }
ngOnInit() {
this.safeHtml = this.sanitizer.bypassSecurityTrustHtml(this.html);
}
}

Angular Source Code

// auth-interceptor.service.ts
import { Injectable, Injector } from '@angular/core';
// ng 4.3
import { HttpInterceptor,
HttpRequest,
HttpHandler,
HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
import { AuthService } from '../shared/services/auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthInterceptorService implements HttpInterceptor {
constructor(private authService: AuthService) {
console.log('Interceptor created');
}
intercept(request: HttpRequest<any>,
next: HttpHandler): Observable<HttpEvent<any>> {
console.log ('Intercepter ', request.url, request.method);
//example only
console.log('token ', this.authService.getToken());
if (this.authService.authenticated) {
request = request.clone({
setHeaders: {
Authorization: `JWT ${this.authService.getToken()}`
}
});
}
return next.handle(request);
}
}
// auth.guard.ts
import { AuthService } from './../services/auth.service';
import { Injectable } from '@angular/core';
import { CanActivate,
ActivatedRouteSnapshot,
RouterStateSnapshot,
Router} from '@angular/router';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService,
private router: Router) {
}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
if (this.authService.authenticated) {
return true;
}
this.router.navigateByUrl('/auth/login');
return false;
}
}
export class Brand {
id: number;
name: string;
}
<h1>Checkout Details</h1>
<form [formGroup]="form" >
<p>
<label>Full Name:</label>
<input type="text" formControlName="fullName" >
</p>
<p>
<label>State:</label>
<select formControlName="state" >
<option [value]='state.id' *ngFor="let state of states$ | async">{{state.name}}</option>
</select>
</p>
<p>
<label>City:</label>
<select formControlName="city" >
<option [value]='city.id' *ngFor="let city of cities$ | async">
{{city.name}}</option>
</select>
</p>
<p>
<label>Country</label>
<input type="text" formControlName="country" >
IN or India
</p>
<p>
<button type="submit" [disabled]="!form.valid">Submit</button>
</p>
</form>
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import {Component, OnInit, Inject, Attribute} from "@angular/core";
import {ActivatedRoute, Params} from "@angular/router";
import { FormGroup, FormControl, Validators,
FormBuilder, Validator, AbstractControl }
from '@angular/forms';
import { environment } from 'src/environments/environment';
function CountryValidator(control: AbstractControl): {
[key: string]: boolean;
} {
console.log("Console ", control.value);
if (control.value === 'IN' || control.value === 'India') {
return; // return undefined means no error
}
return {
invalidCountry: true
};
}
interface State {
code: string;
id: number;
name: string;
}
interface City {
code: string;
id: number;
name: string;
stateId: number;
}
import {filter, map} from 'rxjs/operators';
@Component({
selector: 'app-checkout',
templateUrl: './checkout.component.html',
styleUrls: ['./checkout.component.scss']
})
export class CheckoutComponent implements OnInit {
states$: Observable<State[]>;
cities$: Observable<City[]>;
form: FormGroup;
fullNameControl:FormControl;
stateControl:FormControl;
cityControl:FormControl;
countryControl:FormControl;
constructor(
private route: ActivatedRoute,
private http: HttpClient,
formBuilder: FormBuilder
) {
this.fullNameControl = new FormControl("", Validators.required);
this.stateControl = new FormControl("");
this.cityControl = new FormControl("");
this.countryControl = new FormControl("", CountryValidator);
this.form = formBuilder.group({
"fullName": this.fullNameControl,
"state": this.stateControl,
"city": this.cityControl,
"country": this.countryControl
});
}
ngOnInit() {
this.states$ = this.http.get<State[]>(`${environment.apiEndPoint}/api/states`);
this.stateControl.valueChanges
.pipe(filter ( (value:any) => !!value))
.subscribe ( (value: any) => {
this.cities$ = this.http.get<City[]>(`${environment.apiEndPoint}/api/cities?stateId=${value}`);
});
}
}
import { HttpClient } from '@angular/common/http';
import { Injectable, Inject, ErrorHandler } from "@angular/core";
import {Location} from "@angular/common";
import {Router} from "@angular/router";
import { environment } from '../../environments/environment';
// goes into providers section of app.module.ts
/*
{
provide: ErrorHandler,
useClass: ErrorHandlerService
},
*/
@Injectable({
providedIn: 'root'
})
export class ErrorHandlerService implements ErrorHandler {
constructor(private location: Location,
private http: HttpClient ) {
}
public handleError( error: any ) : void {
// Log to the console.
try {
console.log("Custom error handler");
console.group( "ErrorHandler" );
console.error( error.message );
console.error( error.stack );
console.groupEnd();
this.http.post(`${environment.apiEndPoint}/logs/errors`,
{
message: error.message,
trace: error.stack
})
.subscribe( (savedError) => {
console.log('error saved successfully')
}, (err: any) => {
console.log('error while posting errors to server ', err)
})
} catch ( handlingError ) {
console.group( "ErrorHandler" );
console.warn( "Error when trying to output error." );
console.error( handlingError );
console.groupEnd();
}
}
}
// ng g pipe shared/pipes/filter.pipe.ts
// shared/pipes/filter.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
// {{ dataItems | filter:'year':'<':2010}}
@Pipe({
name: 'filter'
})
export class FilterPipe implements PipeTransform {
transform(items: any[],
field: string,
predicate: string,
value: any): any[] {
if (!items || !field || !predicate || !value) {
return items;
}
if (predicate == '>') {
// return items.filter(item => item[field] > value)
return items.filter(function(item: any):boolean {
return item[field] > value
})
}
if (predicate == '<') {
return items.filter(item => item[field] < value)
}
if (predicate == '==') {
return items.filter(item => item[field] == value)
}
return items;
}
}
//shared/directives/highlight.directive.ts
// ng g directive shared/directives/highlight
import { Directive,
OnInit,
OnDestroy,
Input,
Output,
EventEmitter,
HostListener,
ElementRef,
Renderer2
} from '@angular/core';
@Directive({
// [] must
selector: '[appHighlight]',
exportAs: 'appHighlight'
})
export class HighlightDirective implements OnInit, OnDestroy {
// appHighlight="lightgreen"
@Input("appHighlight")
color: string;
@Output("appHighlightChange")
colorChange: EventEmitter<string> = new EventEmitter();
constructor(private hostElement: ElementRef,
private renderer: Renderer2) {
console.log("Highlight directive created");
}
ngOnInit() {
console.log("highlight init");
console.log("Color ", this.color);
}
ngOnDestroy() {
console.log("highlight destroy");
}
@HostListener('click')
onClick() {
console.log("Directive click");
this.colorChange.emit("red");
}
@HostListener('mouseenter')
onEnter() {
this.renderer
.setStyle(this.hostElement.nativeElement,
'background',
this.color);
}
@HostListener('mouseleave')
onLeave() {
this.renderer
.removeStyle(this.hostElement.nativeElement,
'background');
}
setColor(color: string) {
console.log('set color ', color);
this.color = color;
}
}
<h2>Product List</h2>
<table>
<tr>
<th>Name</th>
<th>Price</th>
<th>Year</th>
<th>+Cart</th>
</tr>
<tr *ngFor="let product of (products$ | async) ">
<td>
<a [routerLink]="['/products', 'edit', product.id, {source:'list'}]" >
{{product.name}}
</a>
</td>
<td>{{product.price}}</td>
<td>{{product.year}}</td>
<td>
<button (click)="addToCart(product)">+Cart</button>
</td>
</tr>
</table>
///product/services/product.service.ts
import { environment }
from './../../../environments/environment';
import { Product } from './../models/product';
import { Brand } from './../models/brand';
import { Observable } from 'rxjs';
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
console.log("ENV ", environment)
@Injectable({
providedIn: 'root'
})
export class ProductService {
constructor(private http: HttpClient) { }
// GET /api/products
getProducts(): Observable<Product[]> {
//FIXME: implement get api for products
return this.http
.get<Product[]>(`${environment.apiEndPoint}/api/products`);
}
// GET /api/products
searchProducts(q: string): Observable<Product[]> {
return this.http.get<Product[]>(`${environment.apiEndPoint}/api/products?q=${q}`);
}
// GET /api/products/100
getProduct(id: any): Observable<Product> {
return this.http
.get<Product>(`${environment.apiEndPoint}/api/products/${id}`);
}
// Cache
// Option 1. In memory JS [on refresh, removed]
// Option 2: browser storage: sessionStorage, per tab based, works on refresh
// closing tab, remove the sessionStorage
// Option 3: browser storage: localStorage: persistent,
// remains active on closing browser, shutdown system
storage: Storage = window.localStorage;
// GET /api/brands
getBrands(): Observable<Brand[]> {
//todo: check if cache present, serve from cache
// let brandsJson = this.storage.getItem("brands");
// if (brandsJson) {
// console.log("Serving brands from cache ");
// //TODO: convert to observable
// let brands: Brand[] = <Brand[]> JSON.parse(brandsJson);
// return Observable.of(brands);
// }
console.log("Serving from server");
return this.http
.get<Brand[]>(`${environment.apiEndPoint}/api/brands`)
}
// update existing product
// PUT /api/products/12345
// {{product json data}}
// response
// updated product data
// to create new product
// POST /api/products
// {{product json data without id}}
// response
// updated product data with id
saveProduct(product: Product):Observable<Product> {
if (product.id) { // update
return this.http
.put<Product>(`${environment.apiEndPoint}/api/products/${product.id}`,
product);
} else { //create
return this.http
.post<Product>(`${environment.apiEndPoint}/api/products`,
product);
}
}
deleteProduct(id: number): Observable<any> {
return this.http
.delete(`${environment.apiEndPoint}/api/products/${id}`)
}
}
export class Product {
id: number;
name: string;
price: number;
year: number;
brandId: number; // reference to brand model
}
// resolver
import { ProductService } from './../services/product.service';
import { Injectable } from '@angular/core';
import { Product } from '../models/product';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ProductsResolveService implements Resolve<Product[]> {
constructor(private productService: ProductService) { }
resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<any>|Promise<any>|any {
return this.productService.getProducts();
}
}
import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
import { Observable } from 'rxjs';
import { Editable } from '../models/editable';
@Injectable({
providedIn: 'root'
})
export class SaveAlertGuard implements CanDeactivate<Editable> {
canDeactivate(target: Editable) {
if (target.isSaved())
return true;
return window.confirm("Unsaved changes, continue?")
}
}
// ng g pipe shared/pipes/sort.pipe.ts
//shared/pipes/sort.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'sort',
pure: false // by default is true
})
export class SortPipe implements PipeTransform {
// stateful pipe
sortedItems: any[];
actualItems: any[];
// transform is called all times if pure is set to false
// transform is called
// whenever object changed if pure set to true
transform(items: any[],
fieldName: string,
order: string = 'asc'): any {
console.log('sort pipe transform called', items, fieldName)
if (!items || !fieldName) {
return items;
}
if (items !== this.actualItems) {
this.actualItems = items;
} // FIXME
console.log('in sort', order);
if (order === 'desc') {
return items.sort ( (left, right) => {
// console.log(left, right);
if (left[fieldName] < right[fieldName])
return 1;
if (left[fieldName] > right[fieldName])
return -1;
return 0;
})
}
//FIXME:
// desc
return items.sort ( (left, right) => {
console.log(left, right);
if (left[fieldName] < right[fieldName])
return -1;
if (left[fieldName] > right[fieldName])
return 1;
return 0;
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment