ronaldkwandy

Untitled

Jul 19th, 2020
1,889
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { HttpParams } from '@angular/common/http';
  2.  
  3. import * as moment from 'moment';
  4. import { GaPagingRequest } from './gaji-id-api-request.model';
  5.  
  6. export interface GaFieldMappingHint {
  7.   model: string;
  8.   api?: string;
  9.   dataType?: string | Function;
  10. }
  11.  
  12. export class GaModelMapper<T> {
  13.   private _fieldMappingHints: GaFieldMappingHint[] = null;
  14.  
  15.   constructor(public modelSignature: any = null) {
  16.     if (this.modelSignature == null) { return; }
  17.  
  18.     this._fieldMappingHints = this.modelSignature['fieldMappingHints'];
  19.   }
  20.  
  21.   public toModel(json: any): T {
  22.     if (json === undefined || json === null) { return null; }
  23.  
  24.     const model = this.newModelInstance(this.modelSignature);
  25.  
  26.     for (const prop in model) {
  27.       if (typeof model[prop] !== 'function') { // handle only field member, not function member
  28.         const mappedVal = this.attemptMapping(model, prop, json);
  29.         if (mappedVal !== null && mappedVal !== undefined) { model[prop] = mappedVal; }
  30.       }
  31.     }
  32.  
  33.     return model;
  34.   }
  35.  
  36.   public toModelArray(jsonArr: any[]): T[] {
  37.     const ms: T[] = [];
  38.     for (const json of jsonArr) { ms.push(this.toModel(json)); }
  39.     return ms;
  40.   }
  41.  
  42.   public toJson(model: T, depth: number = 0): Object {
  43.     const json = {};
  44.  
  45.     for (const prop in model) {
  46.       if (model[prop] !== undefined && typeof model[prop] !== 'function') {
  47.         const hint = this.findMappingHint(model, prop);
  48.         const jsonPropName = (hint !== null && hint.api) ? hint.api : prop;
  49.         const currVal: any = model[prop];
  50.         const maxDepth = depth - 1 < 0 ? 0 : depth - 1;
  51.  
  52.         if (model[prop] instanceof Array) {
  53.           json[jsonPropName] = this.toJsonArray(currVal, maxDepth);
  54.         } else {
  55.           if (depth === 0) {
  56.             if (currVal !== null && currVal['id'] !== undefined && currVal['id'] !== null) {
  57.               json[jsonPropName] = { id: currVal['id'] };
  58.             } else {
  59.               if (hint !== null && hint.dataType === 'date') {
  60.                 json[jsonPropName] = moment(currVal).toISOString();
  61.               } else {
  62.                 json[jsonPropName] = currVal;
  63.               }
  64.             }
  65.           } else if (depth > 0) {
  66.             if (model[prop] instanceof Array) {
  67.               json[jsonPropName] = this.toJsonArray(currVal, maxDepth);
  68.             } else {
  69.               if (hint !== null && hint.dataType === 'date') {
  70.                 json[jsonPropName] = moment(currVal).toISOString();
  71.               } else {
  72.                 if (currVal === null || currVal instanceof Object === false) {
  73.                   json[jsonPropName] = currVal;
  74.                 } else {
  75.                   json[jsonPropName] = this.toJson(currVal, maxDepth);
  76.                 }
  77.               }
  78.             }
  79.           }
  80.         }
  81.       }
  82.     }
  83.     return json;
  84.   }
  85.  
  86.   public toJsonArray(model: any, depth): any {
  87.     const list = [];
  88.     for (const prop in model) {
  89.       const currVal: any = model[prop];
  90.       if (model.constructor === Object && model[prop]) {
  91.         list.push(this.toJson(currVal, depth));
  92.       } else {
  93.         list.push(currVal);
  94.       }
  95.     }
  96.     return list;
  97.   }
  98.  
  99.   public toSearchParams(searchParams?: {}, sorts?: {}, paging?: GaPagingRequest): HttpParams {
  100.     let httpParams = new HttpParams();
  101.  
  102.     if (searchParams !== undefined && searchParams !== null) {
  103.       for (const k in searchParams) {
  104.         if (searchParams[k] != null) {
  105.           const hint = this.findSearchMappingHint(k);
  106.  
  107.           if (hint === null) {
  108.             if (moment.isDate(searchParams[k])) {
  109.               httpParams = httpParams.set(k, moment(searchParams[k]).toISOString());
  110.             } else {
  111.               httpParams = httpParams.set(k, searchParams[k]);
  112.             }
  113.           } else {
  114.             const apiPropName = hint.api ? hint.api : k;
  115.             const apiVal = (hint.dataType && hint.dataType === 'date') ? moment(searchParams[k]).toISOString() : searchParams[k];
  116.  
  117.             httpParams = httpParams.set(apiPropName, apiVal);
  118.           }
  119.         }
  120.       }
  121.     }
  122.  
  123.     if (sorts !== undefined && sorts !== null) {
  124.       let sortStr = '';
  125.  
  126.       for (const k in sorts) {
  127.         if (sorts[k] !== undefined) {
  128.           const hint = this.findSearchMappingHint(k);
  129.  
  130.           if (hint === null) {
  131.             sortStr += k + '-' + sorts[k] + ';';
  132.           } else {
  133.             const apiPropName = hint.api ? hint.api : k;
  134.             sortStr += apiPropName + '-' + sorts[k] + ';';
  135.           }
  136.         }
  137.       }
  138.  
  139.       httpParams = httpParams.set('sort', sortStr);
  140.     }
  141.  
  142.     if (paging !== undefined && paging !== null) {
  143.       httpParams = httpParams.set('page', String(paging.page));
  144.       httpParams = httpParams.set('perPage', String(paging.perPage));
  145.     }
  146.  
  147.     return httpParams;
  148.   }
  149.  
  150.   private attemptMapping(model: T, modelPropName: string, json: any): any {
  151.     const hint = this.findMappingHint(model, modelPropName);
  152.     if (hint === null) { return json[modelPropName]; } // no hint? no work... return whatever it is
  153.  
  154.     const apiPropName = hint.api ? hint.api : modelPropName;
  155.     const jsonVal = json[apiPropName];
  156.  
  157.     if (jsonVal === undefined || jsonVal === null) { return; } // huh? prop value undefined / not found ? terminate!
  158.     if (hint.dataType === undefined || hint.dataType === null) { return jsonVal; } // no datatype? return whatever it is
  159.     const hdt = hint.dataType;
  160.  
  161.     // native type handling
  162.     if (hdt === 'string' || hdt === 'number' || hdt === 'boolean') { return jsonVal; } // standard type needs no conversion
  163.     if (hdt === 'date') { return new Date(jsonVal); }
  164.  
  165.     if (typeof hdt === 'function') { return this.customModelMapping(jsonVal, hint); }
  166.  
  167.     console.warn('[GaModelMapper] - unhandled data type!', hdt);
  168.   }
  169.  
  170.   private findSearchMappingHint(modelPropName: string): GaFieldMappingHint {
  171.     if (this._fieldMappingHints === undefined || this._fieldMappingHints === null) { return null; }
  172.  
  173.     for (let idx = 0, len = this._fieldMappingHints.length; idx < len; idx++) {
  174.       const hint = this._fieldMappingHints[idx];
  175.  
  176.       if (hint.model === modelPropName) { return hint; }
  177.     }
  178.  
  179.     return null;
  180.   }
  181.  
  182.   private findMappingHint(model: T, modelPropName: string): GaFieldMappingHint {
  183.     if (model.constructor['fieldMappingHints'] === undefined || model.constructor['fieldMappingHints'] === null) { return null; }
  184.  
  185.     for (let idx = 0, len = model.constructor['fieldMappingHints'].length; idx < len; idx++) {
  186.       const hint = model.constructor['fieldMappingHints'][idx];
  187.  
  188.       if (hint.model === modelPropName) { return hint; }
  189.     }
  190.  
  191.     return null;
  192.   }
  193.  
  194.   private customModelMapping(jsonVal: any, hint: GaFieldMappingHint): any {
  195.     if (jsonVal instanceof Array) {
  196.       return new GaModelMapper(hint.dataType).toModelArray(jsonVal);
  197.     } else {
  198.       return new GaModelMapper(hint.dataType).toModel(jsonVal);
  199.     }
  200.   }
  201.  
  202.   private newModelInstance(type: { new(): T; }): T { return new type(); }
  203. }
Advertisement
Add Comment
Please, Sign In to add comment