Skip to content

Instantly share code, notes, and snippets.

@InsilicoSoft
Created August 3, 2017 08:12
Show Gist options
  • Select an option

  • Save InsilicoSoft/f77d4fa61815eb3acabdc2d92231218d to your computer and use it in GitHub Desktop.

Select an option

Save InsilicoSoft/f77d4fa61815eb3acabdc2d92231218d to your computer and use it in GitHub Desktop.
Angular API Wrapper Service
import { Injectable, isDevMode } from '@angular/core';
import { ConnectionBackend, Http, URLSearchParams, Headers, RequestOptions,
RequestOptionsArgs, Response, RequestMethod } from '@angular/http';
import { ToastrService } from 'ngx-toastr';
import { Observable } from 'rxjs/Observable';
import * as _ from 'lodash';
import { StorageService } from './storage.service';
import { TokenService } from './token.service';
import { TranslateService } from '../translations/translate.service';
@Injectable()
export class ApiService {
apiPrefix = isDevMode() ? 'http://localhost:8081/api' : '/api';
timeZoneOffset:number;
private error404 = { status: 404, message: 'Route not found', error: true };
constructor(protected http: Http,
protected tokenService: TokenService,
protected toastr: ToastrService,
protected storage: StorageService,
protected translateService: TranslateService) {
let x = new Date();
this.timeZoneOffset = x.getTimezoneOffset() / -60;
}
private apiRequest(kind:string, ...args):Observable<any> {
if(args) this.injectData(kind, args);
return this.http[kind](...args).flatMap(result => {
// return 404 error unless content-type is JSON
if(this.isJsonContent(result)) {
this.storeData(result);
return Observable.of(result);
}
else return Observable.throw(this.error404);
}).catch(error => {
if(error.status >= 500 && error.status < 600) {
this.toastr.error(this.translateService.translate('generalErrors.error_500'));
}
return Observable.throw(error);
})
}
get(url: string, options?: RequestOptionsArgs): Observable<Response> {
return this.apiRequest('get', url, options);
}
post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
return this.apiRequest('post', url, body, options);
}
put(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
return this.apiRequest('put', url, body, options);
}
delete(url: string, options?: RequestOptionsArgs): Observable<Response> {
return this.apiRequest('delete', url, options);
}
patch(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
return this.apiRequest('patch', url, body, options);
}
private injectData(kind, args) {
let options:Object = this.optionsObjectFromArgs(kind, args) || {},
url = args.shift(),
headers = new Headers({
'X-Auth-Token': this.tokenService.getToken(),
'Content-Type': 'application/json',
'X-Timezone-Offset': this.timeZoneOffset,
'X-User-Lat': this.storage.getData('userLat'),
'X-User-Lng': this.storage.getData('userLng')
});
// modify url - add API prefix
url = this.apiPrefix + url;
// add options headers merged with default data
args.push(_.merge(options, { headers }));
args.unshift(url);
}
private isJsonContent(result) {
return !!result.headers.get('Content-Type').match(/^application\/json/);
}
private storeData(result) {
let token = result.headers.get('X-Auth-Token'),
userLat = result.headers.get('X-User-Lat'),
userLng = result.headers.get('X-User-Lng');
if(token) this.tokenService.setToken(token);
if(userLat && userLng) {
this.storage.storeData('userLat', userLat);
this.storage.storeData('userLng', userLng);
}
}
private optionsObjectFromArgs(kind, args) {
let twoRequiredArgsMethods = ['get', 'delete'],
maximumLength = _.includes(twoRequiredArgsMethods, kind) ? 2 : 3;
if(args.length == maximumLength){
return args.pop()
} else if(args.length + 1 == maximumLength) {
return {}
} else throw 'Unexpected arguments passed to ApiService';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment