Skip to content

Instantly share code, notes, and snippets.

@rahulrsingh09
Forked from jhades/01.ts
Last active August 3, 2019 09:43
Show Gist options
  • Save rahulrsingh09/271aaff4cb134685ed7a62197670938c to your computer and use it in GitHub Desktop.
Save rahulrsingh09/271aaff4cb134685ed7a62197670938c to your computer and use it in GitHub Desktop.
Angular HTTP
import {HttpClientModule} from '@angular/common/http';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {
}
import {Component, OnInit} from '@angular/core';
import {Observable} from "rxjs/Observable";
import {HttpClient} from "@angular/common/http";
import * as _ from 'lodash';
interface User {
id: number;
first_name:string;
last_name:string;
avatar:string;
}
@Component({
selector: 'app-root',
template: `
<ul *ngIf="users; else noData">
<li *ngFor="let user of users">
{{user.first_name}}
- </li>
</ul>
<ng-template #noData>No Data Available</ng-template>
`})
export class AppComponent implements OnInit {
users:User[];
constructor(private http:HttpClient) {
}
ngOnInit() {
this.users = this.httpClient.get<User[]>('https://reqres.in/api/users?page=2').map(value => value['data']);
}
}
import {HttpParams} from "@angular/common/http";
const params = new HttpParams()
.set('orderBy', '"name"')
.set('limitToFirst', "1");
this.users = this.http
.get("https://reqres.in/api/users", {params})
.do(console.log)
.map(data => console.log(data))
const params = new HttpParams();
params.set('orderBy', '"name"')
params.set('limitToFirst', "1");
const params = new HttpParams({
fromString: 'orderBy="name"&limitToFirst=1'
});
const params = new HttpParams({
fromString: 'orderBy="name"&limitToFirst=1'
});
this.users = this.http
.request(
"GET",
"https://reqres.in/api/users",
{
responseType:"json",
params
})
.do(console.log)
.map(data => console.log(data));
const headers = new HttpHeaders()
.set("X-CustomHeader", "custom header value");
this.users = this.http
.get(
"https://reqres.in/api/users",
{headers})
.do(console.log)
.map(data => console.log(data));
httpPutExample() {
const headers = new HttpHeaders()
.set("Content-Type", "application/json");
this.http.put("https://reqres.in/api/users/2",
{
"name": "morpheus",
"job": "zion resident"
},
{headers})
.subscribe(
val => {
console.log("PUT call successful value returned in body",
val);
},
response => {
console.log("PUT call in error", response);
},
() => {
console.log("The PUT observable is now completed.");
}
);
}
httpPatchExample() {
this.http.patch("https://reqres.in/api/users/2",
{
"name": "morpheus",
"job": "zion resident"
})
.subscribe(
(val) => {
console.log("PATCH call successful value returned in body",
val);
},
response => {
console.log("PATCH call in error", response);
},
() => {
console.log("The PATCH observable is now completed.");
});
}
httpDeleteExample() {
this.http.delete("https://reqres.in/api/users/2")
.subscribe(
(val) => {
console.log("DELETE call successful);
},
response => {
console.log("DELETE call in error", response);
},
() => {
console.log("The DELETE observable is now completed.");
});
}
httpPostExample() {
this.http.post("https://reqres.in/api/users/2'",
{
"name": "morpheus",
"job": "leader"
})
.subscribe(
(val) => {
console.log("POST call successful value returned in body",
val);
},
response => {
console.log("POST call in error", response);
},
() => {
console.log("The POST observable is now completed.");
});
}
duplicateRequestsExample() {
const httpGet$ = this.http
.get("/courses.json")
.map(data => _.values(data));
httpGet$.subscribe(
(val) => console.log("logging GET value", val)
);
this.courses$ = httpGet$;
}
// put this next to the other RxJs operator imports
import 'rxjs/add/operator/shareReplay';
const httpGet$ = this.http
.get("/courses.json")
.map(data => _.values(data))
.shareReplay();
import 'rxjs/add/observable/forkJoin';
parallelRequests() {
const parallel$ = Observable.forkJoin(
this.http.get('/courses/-KgVwEBq5wbFnjj7O8Fp.json'),
this.http.get('/courses/-KgVwECOnlc-LHb_B0cQ.json')
);
parallel$.subscribe(
values => {
console.log("all values", values)
}
);
}
sequentialRequests() {
const sequence$ = this.http.get<Course>(
'/courses/-KgVwEBq5wbFnjj7O8Fp.json')
.switchMap(course => {
course.description+= ' - TEST ';
return this.http.put(
'/courses/-KgVwEBq5wbFnjj7O8Fp.json',
course)
});
sequence$.subscribe();
}
sequentialRequests() {
const sequence$ = this.http.get<Course>(
'/courses/-KgVwEBq5wbFnjj7O8Fp.json')
.switchMap(course => {
course.description+= ' - TEST ';
return this.http.put('/courses/-KgVwEBq5wbFnjj7O8Fp.json', course)
},
(firstHTTPResult, secondHTTPResult) =>
[firstHTTPResult, secondHTTPResult]);
sequence$.subscribe(
values => console.log("result observable ", values)
);
}
throwError() {
this.http
.get("/api/simulate-error")
.catch( error => {
// here we can show an error message to the user,
// for example via a service
console.error("error catched", error);
return Observable.of({description: "Error Value Emitted"});
})
.subscribe(
val => console.log('Value emitted successfully', val),
error => {
console.error("This line is never called ",error);
},
() => console.log("HTTP Observable completed...")
);
}
import { Observable } from 'rxjs';
import {Injectable} from '@angular/core';
import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http';
import { HttpErrorResponse } from "@angular/common/http";
@Injectable()
export class AngularInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).do(event => {}, err => {
if(err instanceof HttpErrorResponse){
console.log("Error Caught By Interceptor");
//Observable.throw(err);
}
});
}
}
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [
[ { provide: HTTP_INTERCEPTORS, useClass:
AngularInterceptor, multi: true } ]
],
bootstrap: [AppComponent]
})
export class AppModule {
}
longRequest() {
const request = new HttpRequest(
"POST", "/api/test-request", {},
{reportProgress: true});
this.http.request(request)
.subscribe(
event => {
if (event.type === HttpEventType.DownloadProgress) {
console.log("Download progress event", event);
}
if (event.type === HttpEventType.UploadProgress) {
console.log("Upload progress event", event);
}
if (event.type === HttpEventType.Response) {
console.log("response received...", event.body);
}
}
);
}
//Simple Angular Service Call using Observable
this._service.getData().subscribe(
(data) => console.log('onNext is called Data is ',data),
(error) => console.log("Error is: ", error),
() => console.log('onCompleted called you can do stuff like navigate to a
new page when observable stops emitting values')
);
ngOnInit() {
let character = this.http.get('https://swapi.co/api/people/1').map(res => res.json());
let characterHomeworld = this.http.get('http://swapi.co/api/planets/1').map(res => res.json());
Observable.forkJoin([character, characterHomeworld]).subscribe(results => {
// results[0] is our character
// results[1] is our character homeworld
results[0].homeworld = results[1];
this.loadedCharacter = results[0];
});
}
this.service.get()
.do(u => this.<your variable> = u) //.do just invokes the function. does not manipulate the stream,
//return value is ignored.
.flatMap(u => this.userService.getPreferences(u.username))
.subscribe(p => this.<yourvariable> = p);
//enhancing Search using switch maps
this.searchField.valueChanges
.debounceTime(400)
.switchMap(term => this.searchService.search(term)) // it waits when the searchField Stops emitting values
//and then switches to new observable
.subscribe((result) => {
this.result = result.artists.items
});
//Parent Template
<input mdInput type="text" placeholder="Enter" #parentInput (keyup)="0"> // key up a sample dummy event to propagte value
// Child Template
<app-childparent [valuepassed]="parentInput.value" (toParent)="childValue = $event"></app-childparent>
//The magic happens in the child component always
//Child Component
//The value passed by the parent component is parentInput.value we make use of Input decorator in child component
//to use this
@Input() valuepassed : string;
//Now Comes the output decorator to pass the value from child to parent
//Child template
<input mdInput type="text" placeholder="Enter" #childInput (keyup)="onChange(childInput.value)">
//Child Component
@Output() toParent : new EventEmitter<string>;
onChange(value) { this.toParent.emit(value); }
//now we put this onthe Child decorator and use to notify the parent.
//pass data to this component like from any other component
<dynamic [componentData] = "componentData"></dynamic>
// Dynamic Logic
import { Component, OnInit, Input, ViewChild, ViewContainerRef, ComponentFactoryResolver, ReflectiveInjector } from '@angular/core';
import { AngularService } from "app/shared/angular.service";
import { HelloWorldComponent } from 'app/dynamic-component/dynamic/hello-world-component';
import { WorldHelloComponent } from './world-hello-component';
@Component({
selector: 'dynamic',
entryComponents: [HelloWorldComponent, WorldHelloComponent],
template: `<div #dynamicContainer></div>`
})
export class DynamicComponent implements OnInit{
currentComponent = null;
@ViewChild('dynamicContainer' , {read : ViewContainerRef}) decorator : ViewContainerRef; // this is the container where we
// we will load our dynamic component in short Represents a container where one or more Views can be attached.
@Input() set componentData (data : {component: any , inputs :any}){ // getting the input from the called component which instantiates this component
if (!data){
return;
}
// Inputs need to be in the following format to be resolved properly
let inputProviders = Object.keys(data.inputs).map((inputName) => {return {provide: inputName, useValue: data.inputs[inputName]};});
let resolvedInputs = ReflectiveInjector.resolve(inputProviders);
// We create an injector out of the data we want to pass down and this components injector
let injector = ReflectiveInjector.fromResolvedProviders(resolvedInputs, this.decorator.parentInjector);
// We create a factory out of the component we want to create
let factory = this.resolver.resolveComponentFactory(data.component);
// We create the component using the factory and the injector
let component = factory.create(injector);
//console.log(component.hostView);
// We insert the component into the dom container
this.decorator.insert(component.hostView);
// We can destroy the old component is we like by calling destroy
// keep this if you want only one instacne of the component as in this example else remove it and play around
if (this.currentComponent) {
this.currentComponent.destroy();
}
this.currentComponent = component;
this.currentComponent.instance.ref = component; // this method passes the ref of the component to the dynamic component which helps
//us to destroy the component at will
}
constructor(private resolver : ComponentFactoryResolver) {}
ngOnInit() {
}
}
// File upload using FormData in Angular using a Loopback Node js Hereoku api . For more info on backend please comment
// We are making use of FormData to save data to our Server and retrive and Dowload from it.
// Making use of Reactive Form to get the Data in the Format we want
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<mat-input-container>
<input matInput type="text" id="name" placeholder="Enter Name" formControlName="name">
</mat-input-container>
<button mat-raised-button color="primary" type="button" (click)="fileInput.click()">Import file</button> {{ fileInput.value }}
<input type="file" (change)="onFileChange($event)" #fileInput [style.display]="'none'">
<button mat-mini-fab color="warn" type="button" (click)="clearFile()">clear</button>
<button mat-raised-button color="primary" type="submit" [disabled]="form.invalid || loading">Submit
<i class="fa fa-spinner fa-spin fa-fw" *ngIf="loading"></i>
</button>
</form>
// This is the bare Bones to it this Form helps us create data in the following manner
{
name: "Rahul",
avatar: {
filename: "Mee.png",
filetype: "image/png",
value: "XXXXX"
}
}
// The bare bones to the Component File
onFileChange(event){
if(event.target.files.length > 0){
let file = event.target.files[0];
this.form.get('avatar').setValue(file);
}
}
private prepareSave(): any {
let input = new FormData();
input.append('name', this.form.get('name').value);
input.append('avatar', this.form.get('avatar').value);
return input;
}
onSubmit(){
const formModel = this.prepareSave();
this.client.uploadFiles(formModel).subscribe(data => {
this.image_src = "https://loopback-angular-starterkit.herokuapp.com/api/Uploads/images/download/"+fileName;
console.log(data);
});
}
// Here we Listen to File Change Event when we trigger file select and then select the first file
// from the list as this is not multiselect enabled. And set the value to the form
// we construct the FormData by appending data to it and passing it to the onSubmit method which calls the Loopback rest end.
// For more info on Rest end points feel free to check this link https://github.com/rahulrsingh09/AngularConcepts/blob/c187917c7895ea95f5ef8b2ffac546b5324dcde2/src/app/shared/angular.service.ts#L128
// Here we are making uisng of the canActivate Guard which will make sure that the component will load only in cases where the
// route param matches the one the guard is expecting .
import {CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router} from "@angular/router";
import {Injectable} from "@angular/core";
import {Observable} from "rxjs";
@Injectable()
export class AuthGuard implements CanActivate{
constructor(protected router: Router){}
canActivate(route: ActivatedRouteSnapshot,
state: RouterStateSnapshot):Observable<boolean> | boolean{
console.log("In Can Activate AuthGuard");
if(route.params['key'] == "X"){
return true;
}
this.router.navigate(['/home',{message:"Not Authorised"}]);
return false;
}
}
// The Gaurd is activated by placing it in the routes files like
{ path: 'guardcheck', component: CheckComponent , canActivate: [AuthGuard]},
private handleError<T> (operation = 'operation', result?: T) {
return (error: any): Observable<T> => {
// TODO: send the error to remote logging infrastructure
console.error(error); // log to console instead
// TODO: better job of transforming error for user consumption
console.log(`${operation} failed: ${error.message}`);
// Let the app keep running by returning an empty result.
return of(result as T);
};
}
// RxJS tap operator, which looks at the observable values, does something with those values,
// and passes them along. The tap call back doesn't touch the values themselves
// Real world Scenario
get(): Observable<any[]>{
return this.httpClient.get<User[]>('https://reqres.in/api/users', {params})
.map(value => value['data'])
.pipe(
tap(_ => console.log(`Tapping into each observable data`+ _))
,catchError(this.handleError('error handling', []))
);
}
// How to add High Charts to Angular Application I am using https://www.npmjs.com/package/angular2-highcharts for this Demo
// You need to make the following Changes to your app.module.ts when trying to get HighCharts Working
import {ChartModule} from "angular2-highcharts";
import {HighchartsStatic} from "angular2-highcharts/dist/HighchartsService";
export function highchartsFactory() { // this was done to add features like exporting the chart to pdf or adding drilldown
// functionality which you may need in detailed charts. You may skip this if you need basic ones
var hc = require('highcharts');
var hcm = require('highcharts/highcharts-more');
var exp = require('highcharts/modules/exporting');
var drill = require('highcharts/modules/drilldown');
hcm(hc);
exp(hc);
drill(hc)
return hc;
}
@NgModule({
..
providers: [
{
provide: HighchartsStatic,
useFactory: highchartsFactory
}
],
})
// Start using like in this link https://github.com/rahulrsingh09/AngularConcepts/tree/master/src/app/charts
// Look below for samples of the same
// How to use events in the component
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute, Event, GuardsCheckStart, RoutesRecognized, NavigationStart } from "@angular/router";
@Component({
selector: 'app-guards',
templateUrl: './guards.component.html',
styleUrls: ['./guards.component.css']
})
export class GuardsComponent implements OnInit {
constructor(private router:Router,) {
router.events.subscribe(event => {
if(event instanceof NavigationStart) {
console.log("GuardsCheckStart event"); // with this you can have loader signs for component loading via
// guards or make use of these events to display
// proper error events at where the router event failed for the user i:e Auth
// and also youcan refer to services at different stages of the routing events
}
});
}
}
// the first thing is the Router Set up to use Resolve
export const Routes: RouterConfig = [
{ path: 'testing', component: ResolvedComponent, resolve: { data: myResolver } }
];
// Resolver
@Injectable()
export class FireAuthResolve implements Resolve<any> {
constructor(private localStorage: LocalStorageService) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any>|Promise<any>|any {
if (localStorage.getItem("something")){
return Observable.of(true);
} else {
return Observable.of(false);
}
}
}
// In the component
constructor(
private route: ActivatedRoute
) {}
ngOnInit() {
myData = this.route.snapshot.data['data'];
}
// Shadow DOM - is an internal DOM of your component that is defined by you (as a creator of the component)
// and hidden from an end-user. For example:
@Component({
selector: 'some-component',
template: `
<h1>I am Shadow DOM!</h1>
<h2>Nice to meet you :)</h2>
<ng-content></ng-content>
`;
})
class SomeComponent { /* ... */ }
// Light DOM - is a DOM that an end-user of your component supply into your component. For example:
@Component({
selector: 'another-component',
directives: [SomeComponent],
template: `
<some-component>
<h1>Hi! I am Light DOM!</h1>
<h2>So happy to see you!</h2>
</some-component>
`
})
class AnotherComponent { /* ... */ }
// The difference between @ViewChildren and @ContentChildren is that @ViewChildren look for elements in Shadow DOM
// while @ContentChildren look for them in Light DOM.
// Head or Main component
<html>
<head>
<title>ViewEncapsulation Demo</title>
<style>
.test {background: green;}
</style>
</head>
<body>
<div class="test">Test!</div>
<my-app>
Loading...
</my-app>
</body>
</html>
// Child Component
import {Component, ViewEncapsulation} from 'angular2/core';
@Component({
selector: 'my-app',
encapsulation: ViewEncapsulation.Native, // the default encapulsation by Angular , Emulated - uses browsers native styling
// none - allows atyling to trickle down to the child components from the main component
styles: [`
:host {
display: block;
padding: 10px;
background: red;
}
`],
template: `
<div class="test">
<div>
Title: {{ title }}
</div>
<input type="text" [(ngModel)]="title">
</div>
`
})
export class AppComponent {
public title = 'Hello!';
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment