Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deep copying objects in Angular

Tags:

angular

AngularJS has angular.copy() to deep copy objects and arrays.

Does Angular also have something like that?

like image 290
Ankit Singh Avatar asked Mar 21 '16 06:03

Ankit Singh


People also ask

Is Angular copy a deep copy?

Explanation : = represents a reference whereas angular. copy() creates a new object as a deep copy. Using = would mean that changing a property of response.

What is deep cloning in Angular?

You can deep copy an object in Angular by using lodash's cloneDeep method: Install lodash with yarn add lodash or npm install lodash . In your component, import cloneDeep and use it: import * as cloneDeep from 'lodash/cloneDeep'; ...

What is deep copy and shallow copy in Angular?

A deep copy means that all of the values of the new variable are copied and disconnected from the original variable. A shallow copy means that certain (sub-)values are still connected to the original variable.

How do you copy a deep object?

Copy an Object With Object.assign() was the most popular way to deep copy an object. Object. assign() will copy everything into the new object, including any functions. Mutating the copied object also doesn't affect the original object.


Video Answer


5 Answers

You can also use:

JSON.parse(JSON.stringify(Object))

if it's on your scope, it's in every Angular component, directive, etc. and it's also on every node environment.

Unless you have a circular reference, it should work and will effectively dissociate your variable reference to the original object.

like image 54
Gabriel Balsa Cantú Avatar answered Oct 20 '22 17:10

Gabriel Balsa Cantú


This question isn't a duplicate of How can I use angular.copy in angular 2 because the OP is asking about deep copying objects. The linked answer recommends Object.assign() which doesn't make a deep copy.

Actually, using Angular2 doesn't restrict you from using other libraries like jQuery for deep copying objects with their $.clone() function or lodash with _.cloneDeep().

The most common libraries have their typings available via typings CLI tools so even when transpiling from TypeScript you can seamlessly use anything you want.

Also see: What is the most efficient way to deep clone an object in JavaScript?

like image 29
martin Avatar answered Oct 20 '22 17:10

martin


Another option is to implement your own function:

/**
 * Returns a deep copy of the object
 */
public static deepCopy(oldObj: any) {
    var newObj = oldObj;
    if (oldObj && typeof oldObj === "object") {
        if (oldObj instanceof Date) {
           return new Date(oldObj.getTime());
        }
        newObj = Object.prototype.toString.call(oldObj) === "[object Array]" ? [] : {};
        for (var i in oldObj) {
            newObj[i] = this.deepCopy(oldObj[i]);
        }
    }
    return newObj;
}
like image 23
Andrea Ialenti Avatar answered Oct 20 '22 17:10

Andrea Ialenti


You can deep copy an object in Angular by using lodash's cloneDeep method:

Install lodash with yarn add lodash or npm install lodash.

In your component, import cloneDeep and use it:

import * as cloneDeep from 'lodash/cloneDeep';
...
clonedObject = cloneDeep(originalObject);

It's only 18kb added to your build, well worth for the benefits.

I've also written an article here, if you need more insight on why using lodash's cloneDeep.

like image 17
BogdanC Avatar answered Oct 20 '22 18:10

BogdanC


Create helper class with name deepCopy.ts

/*
* DeepCopy class helps to copy an Original Array or an Object without impacting on original data
*/

export class DeepCopy {

  static copy(data: any) {
    let node;
    if (Array.isArray(data)) {
      node = data.length > 0 ? data.slice(0) : [];
      node.forEach((e, i) => {
        if (
          (typeof e === 'object' && e !== {}) ||
          (Array.isArray(e) && e.length > 0)
        ) {
          node[i] = DeepCopy.copy(e);
        }
      });
    } else if (data && typeof data === 'object') {
      node = data instanceof Date ? data : Object.assign({}, data);
      Object.keys(node).forEach((key) => {
        if (
          (typeof node[key] === 'object' && node[key] !== {}) ||
          (Array.isArray(node[key]) && node[key].length > 0)
        ) {
          node[key] = DeepCopy.copy(node[key]);
        }
      });
    } else {
      node = data;
    }
    return node;
  }
}

Import deepCopy file where ever you required and use as below code DeepCopy.copy(arg); , Here arg would either object or array which you want

like image 7
Krishnamraju K Avatar answered Oct 20 '22 16:10

Krishnamraju K