Skip to content

Instantly share code, notes, and snippets.

@hmil
Created November 23, 2017 14:31
Show Gist options
  • Save hmil/41030892313a230031f562a7976b559b to your computer and use it in GitHub Desktop.
Save hmil/41030892313a230031f562a7976b559b to your computer and use it in GitHub Desktop.
Typescript API consumer
export interface AjaxRequest {
url: string;
method?: string;
data?: any;
}
let REPORT_ERRORS = true;
export function disableErrorReporting(): void {
REPORT_ERRORS = false;
}
export function enableErrorReporting(): void {
REPORT_ERRORS = true;
}
export function ajax<T>(req: AjaxRequest): Promise<T> {
return new Promise<T>((resolve, reject) => {
$.ajax({
method: req.method || 'POST',
url: req.url,
headers: {
'X-CSRF-TOKEN': safeGetMetadata('csrf-token'),
'Accept': 'application/json'
},
data: req.data
})
.done(resolve)
.fail((data) => {
if (REPORT_ERRORS) {
let err = __(`error-status-${data.status}`);
if (data.responseJSON && data.responseJSON.error) {
err = data.responseJSON.error;
}
if (err) {
showNotification("error", __("error-toast-title"), err);
}
}
reject(data);
});
});
}
import { buildQueryString } from './URL';
import { QueryParams } from '../../mixins/Routable';
export class BaseResource<T, DTO_IN, DTO_OUT> {
constructor(
public readonly url: string,
protected deserialize: (d: DTO_IN) => T,
protected serialize: (m: T) => DTO_OUT,
public readonly params?: QueryParams) {
}
/**
* Builds the URL for this resource with additional querystring parameters.
*
* @param params Additonal query parameters
*/
protected buildURL(url: string, params?: QueryParams): string {
const queryString = buildQueryString(Object.assign({} as QueryParams, this.params, params));
return url + queryString;
}
}
import { Course, CourseRecvDTO } from '../../models/Course';
import { CRUDResource } from './../Resources/CRUDResource';
export const CourseResource = new CRUDResource<Course, CourseRecvDTO, Course>(
'/api/course', Course.fromJSON, c => c);
import { QueryParams } from '../../mixins/Routable';
import { BaseResource } from './BaseResource';
import { ajax } from '../Ajax';
import { IResourceModel } from '../../models/IResourceModel';
export class CRUDResource<T extends IResourceModel, DTO_IN, DTO_OUT> extends BaseResource<T, DTO_IN, DTO_OUT> {
public async index(params?: QueryParams): Promise<T[]> {
return (
await ajax<DTO_IN[]>({
url: this.buildURL(this.url, params),
method: 'GET'
})
).map(this.deserialize);
}
public async get(id: string, params?: QueryParams): Promise<T> {
return this.deserialize(
await ajax<DTO_IN>({
url: this.buildURL(`${this.url}/${id}`, params),
method: 'GET'
})
);
}
public async update(model: T, params?: QueryParams): Promise<T | undefined> {
const res = await ajax<DTO_IN | undefined>({
url: this.buildURL(`${this.url}/${model.id}`, params),
method: 'PUT',
data: {
model: this.serialize(model)
}
});
if (res) {
return this.deserialize(res);
}
return;
}
public async create(model: T, params?: QueryParams): Promise<DTO_IN> {
return await ajax<DTO_IN>({
url: this.buildURL(this.url, params),
method: 'POST',
data: {
model: this.serialize(model)
}
});
}
public async delete(model: T, params?: QueryParams): Promise<void> {
return ajax<void>({
url: this.buildURL(`${this.url}/${model.id}`, params),
method: 'DELETE'
});
}
}
interface QueryParams {
[key: string]: string;
}
export function mergeQueryParams(...p: Array<QueryParams | undefined>): QueryParams {
return Object.assign({}, ...p.filter(p => p != null));
}
export function buildQueryString(params?: QueryParams) {
if (!params) return '';
const query = Object.keys(params).map(k => `${k}=${params[k]}`).join('&');
return (query.length > 0) ? '?' + query : '';
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment