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                1× 1×           1×               1× 1×                   11× 11× 7×   4× 58× 1×     57× 9×     48× 45×     48× 147×   147× 117×   30×   18× 18× 48×   18×   12× 3×   9× 3×     6×         48×       4×       4×                     2× 2× 1× 2× 2×   1×   2×                     2× 2× 1× 2× 2×   1×   1×     1×    
/*
 *  @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));
        }
    }
}