all files / common/core/cloning/ cloning.service.ts

96.36% Statements 53/55
97.06% Branches 33/34
92.31% Functions 12/13
97.92% Lines 47/48
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129                                                          11× 11×   58×     57×     48× 45×     48× 147×   147× 117×   30×   18× 18× 48×   18×   12×               48×                                                                    
/*
 *  @license
 *  Copyright Hôpitaux Universitaires de Genève. All Rights Reserved.
 *
 *  Use of this source code is governed by an Apache-2.0 license that can be
 *  found in the LICENSE file at https://github.com/DSI-HUG/dejajs-components/blob/master/LICENSE
 */
 
import { Injectable } from '@angular/core';
import {Observable,  of as observableOf } from 'rxjs';
 
/**
 * @deprecated 09.01.2017 Use lodash cloneDeep instead
 */
@Injectable()
export class CloningService {
    /**
     * Clone of an object asyncronously
     *
     * @param object  The object to clone.
     * @param type The type of object to clone
     * @return Observable resolving to the cloned object.
     */
    public clone$<T>(object: any, type?: { new(): T } | object): Observable<T> {
        return observableOf(this.cloneSync(object, type));
    }
 
    /**
     * Clone an object or a class
     *
     * @param object  The object to clone.
     * @param target The type or an instance of the target
     * @return The cloned object.
     */
    public cloneSync<T>(obj: object, target?: { new(): T } | object): T {
        if (!target) {
            return JSON.parse(JSON.stringify(obj));
        } else {
            const cloneInternal = (src: any, tgt?: any) => {
                if (!src || typeof src !== 'object') {
                    return src;
                }
 
                if (src instanceof Date) {
                    return new Date(src.getTime());
                }
 
                if (!tgt) {
                    tgt = new src.constructor();
                }
 
                Object.keys(src).forEach((key) => {
                    const val = src[key];
 
                    if (typeof val !== 'object' || val === null) {
                        tgt[key] = val;
 
                    } else if (Array.isArray(val)) {
                        // just clone arrays (and recursive clone objects inside)
                        const clone = [] as any[];
                        val.forEach((item, index) => {
                            clone[index] = cloneInternal(item);
                        });
                        tgt[key] = clone;
 
                    } else if (val instanceof Date) {
                        tgt[key] = new Date(val.getTime());
 
                    } else if (val instanceof RegExp) {
                        tgt[key] = new RegExp(val);
 
                    } else {
                        tgt[key] = cloneInternal(val);
 
                    }
                });
 
                return tgt;
            };
 
            /** deprecated, replaced by clone array because not working if target is an object */
            Iif (obj && Array.isArray(obj)) {
                return obj.map((o) => this.cloneSync(o, target)) as any;
            }
 
            return cloneInternal(obj, typeof target === 'object' ? target : new target());
        }
    }
 
    /**
     * Clone an Array
     *
     * @param object  The Array to clone.
     * @param target The type or an instance of the target
     * @return The cloned Array.
     */
    public cloneArray<T>(obj: object[], target?: { new(): T } | T[]): T[] {
        if (target && Array.isArray(target)) {
            obj.forEach((o) => {
                const cloned = this.cloneSync(o) as T;
                target.push(cloned);
            });
            return target as T[];
        } else {
            return obj.map((o) => this.cloneSync(o, target));
        }
    }
 
    /**
     * Clone an array asyncronously
     *
     * @param object  The array to clone.
     * @param target The type or an instance of the target
     * @return Observable resolving to the cloned array.
     */
    public cloneArray$<T>(obj: any[], target?: { new(): T } | T[]): Observable<T[]> {
        if (target && Array.isArray(target)) {
            obj.forEach((o) => {
                const cloned = this.cloneSync(o) as T;
                target.push(cloned);
            });
            return observableOf(target);
        } else {
            return observableOf(this.cloneArray(obj, target));
        }
    }
}