The Angular.copy() function selectively copies properties and does not duplicate everything

Exploring a function within a service:

$scope.addPeriod = function(newPeriod) {        
        if(newPeriod.from !== '' && newPeriod.until !== '') {           
            var index = $scope.newPeriods.indexOf(newPeriod);       
            $scope.newPeriods.splice(index, 1); 
            $scope.setHolidayEditions(newPeriod);


            console.log("Check period");
            console.log(newPeriod); // state 1: object newPeriod is as expected, it contains holidayEdtions

            console.log("Check period copy");
            console.log(angular.copy(newPeriod)); // state 2 : object newPeriod is missing the holidayeditions!
            $scope.periods.push(angular.copy(newPeriod)); //original code
            //some more logic irrelevant to the question
        }
}

The issue lies with the angular.copy() method. The structure of the newPeriod object is as follows:

it includes a "from" date and an "until" date, along with an array of magazine objects. In addition, there is the $scope.setHolidayEditions (newPeriod) function, which appends an array of edition objects to each magazine. This function operates correctly, evident from the console output. In the original code, the period is then pushed into an array of periods, which is ultimately displayed on the screen. Presumably, angular.copy() was used to prevent reference issues.

However, the angular.copy() function seems to overlook copying the freshly created editions array within the magazine objects. Is there a rationale for this behavior?

This is essentially what occurs in the service function:

There exists an object named newPeriod, structured like so:

{
  from:"02/10/2015", 
  until:"09/10/2015",
  magazines: [
           {title:"some title", number:"some number", code:"magazineCode"},
           {title:"other title", number:"other number", code:"magazineCode2"}
  ]
}

post the execution of $scope.setHolidayEditions(newPeriod), the object transforms into:

    {
          from:"02/10/2015", 
          until:"09/10/2015",
          magazines: [
                   {title:"some title", number:"some number", code:"magazineCode", holidayEditions:["date","date","date"]},
                   {title:"other title", number:"other number", code:"magazineCode2", holidayEditions:["date","date","date"]}
          ]
}

Nevertheless, after the usage of angular.copy(newPeriod), the object reverts back to its initial form:

 {
      from:"02/10/2015", 
      until:"09/10/2015",
      magazines: [
               {title:"some title", number:"some number", code:"magazineCode"},
               {title:"other title", number:"other number", code:"magazineCode2"}
      ]
    }

It's perplexing how the angular.copy() operation fails to include the holidayEditions array within the magazines. Any insights on this puzzling behavior?

Answer №1

It appears that I faced the same issue some time back, and after careful consideration (among other factors), I opted to utilize lodash, which offers a specific function to address this very problem:

_.cloneDeep(value, [customizer], [thisArg])

This function is designed to create a thorough copy of the provided value. If a customizer is specified, it will be used to generate the cloned values. In cases where the customizer does not return any value, cloning will be managed by the method itself. The customizer is associated with thisArg and called with a maximum of three arguments: (value [, index|key, object]).

Please Note: This approach draws inspiration from the structured clone algorithm. Properties that can be enumerated in arguments objects and objects formed by constructors aside from Object are replicated to basic Object objects. For unclonable entities like functions, DOM nodes, Maps, Sets, and WeakMaps, an empty object will be the result.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Adding data to a URL using jQuery Ajax

I'm currently working on implementing Ajax with jQuery and I have a specific requirement to add data to the URL. Take a look at the code snippet below: var my_website= mysamplesite.com/viewData/"; function displayData(myData) { $.ajax({ t ...

Storing additional data from extra text boxes into your database can be achieved using AJAX or PHP. Would you

A dynamic text box has been created using Jquery/JavaScript, allowing users to click on an "Add More" button to add additional input boxes for entering data. However, a challenge arises when attempting to store this user-generated data in a database. Assi ...

Creating visuals from written content

I am attempting to transform Y[0] into an image rather than text. Currently, it is only displayed as a plain text link and not as an image. <html> <head> <script type="text/javascript"> function modifyContent(){ var rows=document.g ...

Having issues with angular-file-upload failing to include the file in the request

I am currently using angular-file-upload in order to upload an image to a server that is utilizing Node and Express 4.0. However, I am encountering difficulties in accessing the file data on the server. Below is the relevant code snippet: <input type= ...

Enhance the "content switcher" code

I have been working on improving my "contenthandler" function. It currently changes different articles when I click different buttons, which I am satisfied with. However, I believe there may be a better approach to this and would appreciate any advice on h ...

Numerous Controllers in AngularApp failing to function properly

One issue I'm encountering is that only one out of the two controllers within my app seems to be registered: var app = angular.module('MyModule', []); app.controller('FruitCtrl', function($scope) { $scope.fruits = ['appl ...

Unbinding or undoing an 'onclick' event when another 'onclick' event is triggered

I am facing an issue where clicking on elements with 'onclick' functions works as expected, but when I click on a different element with another 'onclick' function, the first one remains active. What I actually want is for the previous ...

How can curly braces be utilized in an array reduce method?

If the function `fn3` is used instead of `fn2` in this code snippet running on node 9.5.0, the `console.log(totalUpvotes)` will display `undefined`. Shouldn't it actually be equal to 92? const posts = [{id: 1, upVotes: 2}, {id:2, upVotes: 89}, {id: ...

Adding JavaScript files to a project in Ionic2 with Angular2 integration

I'm looking to incorporate jQuery into my Ionic2 app, which requires loading several JavaScript files: <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <script type="text/j ...

Ways to modify color while user moves the screen

I'm working with some jQuery code that changes the colors of elements as the user scrolls down, and I want it to revert back to the original color when scrolling back up. However, the script is not behaving as expected... Here is the original working ...

When the scope changes, the AngularJS variables in the view are not updating accordingly

Recently diving into AngularJS has been quite the journey for me. However, I've hit a major roadblock that's had me stumped for the past two days. Here's my dilemma: Despite updating the variable in the controller, my view refuses to reflec ...

jqGrid is failing to display basic JSON data properly

As a newcomer to Jquery and Json, I am struggling with binding a JSON object from a RESTful Webservice written in WCF to jqGrid. Despite saving the JSON object as a static file and attempting to bind it to the grid, I realized that the issue does not lie w ...

The collapsible tree nodes overlap one another in the D3.js visualization

I'm currently working on integrating a d3 code into Power BI for creating a collapsible tree structure. Each node in the tree is represented by a rectangular box, but I've run into an issue where nodes overlap when their size is large. Below is t ...

Transform TypeScript class into an object

Is there a way to transfer all values from one typescript class, Class A, to another matching class, Class B? Could there be a method to extract all properties of Class A as an object? ...

Using AngularJS for dynamically generated HTML elements that have not been loaded into the DOM involves creating an AngularJS directive that manages

Hey there! I'm a newcomer to AngularJs and I'm currently fetching HTML data from C# through an ajax call. I'm attempting to incorporate AngularJs functionality for the dynamically generated HTML, but unfortunately I'm not seeing any Ang ...

Once you have reviewed the initial reply, proceed to send a follow-up message

Once I have received a response from the server for one string, my goal is to send the next JSON object. I need to verify the first object and then proceed to send the second one based on that verification. How should I handle the server's response? ...

Transfer the index of a for loop to another function

Can you explain how to pass the 'i' value of a for loop to a different function? I want to create a click function that changes the left position of a <ul> element. Each click should use values stored in an array based on their index posi ...

Utilize the search bar within a JavaScript function

One issue I am facing is taking an input from a search box and using that value as a parameter for another function. However, every time I click the button, the global variable resets itself when the page refreshes. In my javascript code, this is what I h ...

Is it possible to make a link_to, which is essentially a normal <a href>, clickable through a div that is also clickable?

I am currently dealing with a clickable div element which has a collapse functionality, and there is also a link placed on top of it: <div class="panel-group" id="accordion"> <div class="panel panel-default"> <div class="panel-h ...

Implementing AngularJS to store data in a JSON object

Imagine having an animals.json file with the following details: { "animals": { "elephant": { "size": "large" }, "mouse": { "size": "small" } } } Now, let's say this data is being added to the controller scope: anim ...