Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { HttpParams } from '@angular/common/http';
- import * as moment from 'moment';
- import { GaPagingRequest } from './gaji-id-api-request.model';
- export interface GaFieldMappingHint {
- model: string;
- api?: string;
- dataType?: string | Function;
- }
- export class GaModelMapper<T> {
- private _fieldMappingHints: GaFieldMappingHint[] = null;
- constructor(public modelSignature: any = null) {
- if (this.modelSignature == null) { return; }
- this._fieldMappingHints = this.modelSignature['fieldMappingHints'];
- }
- public toModel(json: any): T {
- if (json === undefined || json === null) { return null; }
- const model = this.newModelInstance(this.modelSignature);
- for (const prop in model) {
- if (typeof model[prop] !== 'function') { // handle only field member, not function member
- const mappedVal = this.attemptMapping(model, prop, json);
- if (mappedVal !== null && mappedVal !== undefined) { model[prop] = mappedVal; }
- }
- }
- return model;
- }
- public toModelArray(jsonArr: any[]): T[] {
- const ms: T[] = [];
- for (const json of jsonArr) { ms.push(this.toModel(json)); }
- return ms;
- }
- public toJson(model: T, depth: number = 0): Object {
- const json = {};
- for (const prop in model) {
- if (model[prop] !== undefined && typeof model[prop] !== 'function') {
- const hint = this.findMappingHint(model, prop);
- const jsonPropName = (hint !== null && hint.api) ? hint.api : prop;
- const currVal: any = model[prop];
- const maxDepth = depth - 1 < 0 ? 0 : depth - 1;
- if (model[prop] instanceof Array) {
- json[jsonPropName] = this.toJsonArray(currVal, maxDepth);
- } else {
- if (depth === 0) {
- if (currVal !== null && currVal['id'] !== undefined && currVal['id'] !== null) {
- json[jsonPropName] = { id: currVal['id'] };
- } else {
- if (hint !== null && hint.dataType === 'date') {
- json[jsonPropName] = moment(currVal).toISOString();
- } else {
- json[jsonPropName] = currVal;
- }
- }
- } else if (depth > 0) {
- if (model[prop] instanceof Array) {
- json[jsonPropName] = this.toJsonArray(currVal, maxDepth);
- } else {
- if (hint !== null && hint.dataType === 'date') {
- json[jsonPropName] = moment(currVal).toISOString();
- } else {
- if (currVal === null || currVal instanceof Object === false) {
- json[jsonPropName] = currVal;
- } else {
- json[jsonPropName] = this.toJson(currVal, maxDepth);
- }
- }
- }
- }
- }
- }
- }
- return json;
- }
- public toJsonArray(model: any, depth): any {
- const list = [];
- for (const prop in model) {
- const currVal: any = model[prop];
- if (model.constructor === Object && model[prop]) {
- list.push(this.toJson(currVal, depth));
- } else {
- list.push(currVal);
- }
- }
- return list;
- }
- public toSearchParams(searchParams?: {}, sorts?: {}, paging?: GaPagingRequest): HttpParams {
- let httpParams = new HttpParams();
- if (searchParams !== undefined && searchParams !== null) {
- for (const k in searchParams) {
- if (searchParams[k] != null) {
- const hint = this.findSearchMappingHint(k);
- if (hint === null) {
- if (moment.isDate(searchParams[k])) {
- httpParams = httpParams.set(k, moment(searchParams[k]).toISOString());
- } else {
- httpParams = httpParams.set(k, searchParams[k]);
- }
- } else {
- const apiPropName = hint.api ? hint.api : k;
- const apiVal = (hint.dataType && hint.dataType === 'date') ? moment(searchParams[k]).toISOString() : searchParams[k];
- httpParams = httpParams.set(apiPropName, apiVal);
- }
- }
- }
- }
- if (sorts !== undefined && sorts !== null) {
- let sortStr = '';
- for (const k in sorts) {
- if (sorts[k] !== undefined) {
- const hint = this.findSearchMappingHint(k);
- if (hint === null) {
- sortStr += k + '-' + sorts[k] + ';';
- } else {
- const apiPropName = hint.api ? hint.api : k;
- sortStr += apiPropName + '-' + sorts[k] + ';';
- }
- }
- }
- httpParams = httpParams.set('sort', sortStr);
- }
- if (paging !== undefined && paging !== null) {
- httpParams = httpParams.set('page', String(paging.page));
- httpParams = httpParams.set('perPage', String(paging.perPage));
- }
- return httpParams;
- }
- private attemptMapping(model: T, modelPropName: string, json: any): any {
- const hint = this.findMappingHint(model, modelPropName);
- if (hint === null) { return json[modelPropName]; } // no hint? no work... return whatever it is
- const apiPropName = hint.api ? hint.api : modelPropName;
- const jsonVal = json[apiPropName];
- if (jsonVal === undefined || jsonVal === null) { return; } // huh? prop value undefined / not found ? terminate!
- if (hint.dataType === undefined || hint.dataType === null) { return jsonVal; } // no datatype? return whatever it is
- const hdt = hint.dataType;
- // native type handling
- if (hdt === 'string' || hdt === 'number' || hdt === 'boolean') { return jsonVal; } // standard type needs no conversion
- if (hdt === 'date') { return new Date(jsonVal); }
- if (typeof hdt === 'function') { return this.customModelMapping(jsonVal, hint); }
- console.warn('[GaModelMapper] - unhandled data type!', hdt);
- }
- private findSearchMappingHint(modelPropName: string): GaFieldMappingHint {
- if (this._fieldMappingHints === undefined || this._fieldMappingHints === null) { return null; }
- for (let idx = 0, len = this._fieldMappingHints.length; idx < len; idx++) {
- const hint = this._fieldMappingHints[idx];
- if (hint.model === modelPropName) { return hint; }
- }
- return null;
- }
- private findMappingHint(model: T, modelPropName: string): GaFieldMappingHint {
- if (model.constructor['fieldMappingHints'] === undefined || model.constructor['fieldMappingHints'] === null) { return null; }
- for (let idx = 0, len = model.constructor['fieldMappingHints'].length; idx < len; idx++) {
- const hint = model.constructor['fieldMappingHints'][idx];
- if (hint.model === modelPropName) { return hint; }
- }
- return null;
- }
- private customModelMapping(jsonVal: any, hint: GaFieldMappingHint): any {
- if (jsonVal instanceof Array) {
- return new GaModelMapper(hint.dataType).toModelArray(jsonVal);
- } else {
- return new GaModelMapper(hint.dataType).toModel(jsonVal);
- }
- }
- private newModelInstance(type: { new(): T; }): T { return new type(); }
- }
Advertisement
Add Comment
Please, Sign In to add comment