Skip to content

Instantly share code, notes, and snippets.

@Devcon4
Last active November 7, 2020 23:30
Show Gist options
  • Select an option

  • Save Devcon4/2d9dab40c1bfe9189a2b9c5d9f4ea026 to your computer and use it in GitHub Desktop.

Select an option

Save Devcon4/2d9dab40c1bfe9189a2b9c5d9f4ea026 to your computer and use it in GitHub Desktop.
httpClient
export class Action<T> {
_subject = new BehaviorSubject<T>(undefined);
public get state() : T {
return this._subject.getValue();
}
public set state(v : T) {
this._subject.next(v);
}
public get subject(): BehaviorSubject<T> {
return this._subject;
}
}
<div style="text-align:center">
<h1>
{{ dataState.subject | async}}
</h1>
</div>
import { Component } from '@angular/core';
import { HttpClient } from 'selenium-webdriver/http';
import { DataService, Data } from './data-service.service';
import { Observable, empty } from 'rxjs';
import { StoreService } from './store.service';
import { map } from 'rxjs/operators';
import { DataStateService } from './data-state.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
strList: string[] = [];
obs: Observable<Data> = empty();
constructor(private store: StoreService, public dataState: GenericStateService<Data>) {
store.appState.subscribe(s => this.strList = s['data']);
}
}
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
HttpModule,
],
providers: [
dataService,
storeService,
dataStateService,
{ provide: 'dataState', useValue: new GenericStateService<Data>() },
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { ResponseContentType } from '@angular/http';
import { of, Observable, throwError, Subscription } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { StoreService } from './store.service';
import { Action, DataStateService } from './data-state.service';
export class Data {
Name: string;
constructor(arg: Partial<Data>) {
Object.assign(this, arg);
}
}
@Injectable({
providedIn: 'root'
})
export class DataService {
constructor(private http: HttpClient, private store: StoreService, private dataState: GenericStateService<Data>) { }
handleError = (error: HttpErrorResponse) => {
if (error.error instanceof ErrorEvent) {
// A client-side or network error occurred. Handle it accordingly.
console.error('An error occurred:', error.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
console.error(
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
}
// return an observable with a user-facing error message
return throwError(
'Something bad happened; please try again later.');
};
dispatchState = <T>(key: string) => {
return (obs: Observable<T>) => {
let unsubFunc = (sub: Subscription) => sub.unsubscribe();
let sub = obs.pipe(map(d => ({key: key, data: d}))).subscribe(this.store.dispatch, undefined, () => unsubFunc(sub));
return obs;
}
}
actionService = <T, U extends Action<T>>(service: U) => {
return (obs: Observable<T>) => {
let unsubFunc = (sub: Subscription) => sub.unsubscribe();
let sub = obs.subscribe(d => service.state = d, undefined, () => unsubFunc(sub));
return obs;
}
}
dataHook = <T>(obs: Observable<T>) => {
return obs.pipe(
catchError(this.handleError),
);
}
getData() {
return this.http.get<string[]>('./api/action/data/ReadList', { responseType: 'json' }).pipe(this.dataHook, this.dispatchState('getData') );
}
getDataMap() {
return this.http.get('./api/action/data/Read').pipe(map(d => new Data(d)), this.dataHook, this.actionService(this.dataState) );
}
}
import { Injectable } from '@angular/core';
import { Data } from './data-service.service';
import { Action } from './action';
@Injectable({
providedIn: 'root'
})
export class DataStateService extends Action<Data> { }
import { Injectable } from '@angular/core';
import { Data } from './data-service.service';
import { Action } from './action';
@Injectable({
providedIn: 'root'
})
export class GenericStateService<T> extends Action<T> { }
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
type action<T> = { key: string, data: T };
@Injectable({
providedIn: 'root'
})
export class StoreService {
appState = new BehaviorSubject<any>({});
constructor() { }
dispatch<T>(action: action<T>) {
this.appState.next(Object.assign(this.appState, reducerOne(action)));
}
}
export function reducerOne<T>(action: action<T>) {
switch (action.key) {
case 'getData':
return { data: action.data };
case 'getDataMap':
return { mapData: action.data };
default:
return {};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment