How can I duplicate an array of objects in javascript?

I'm struggling with a javascript issue that may be due to my lack of experience in the language, but I haven't been able to find a solution yet.

The problem is that I need to create a copy array of an array of objects, modify the data in the copy array without affecting the values in the original array of objects, and then reassign the copy array back to the original one so I can use it again with the initial values in another function.

In a simple program I created, there are two classes - Country which has some properties and a method to update one of these properties, and World which contains an array of countries and a function to update the data for all countries in the array. After calling the changeAllCountriesData function on a World instance, both the countries array and the copyData array have changed unexpectedly.

class Country{
    name; area; population;

    constructor(name, area, population){
        this.name = name;
        this.area = area;
        this.population = population;
    }

    changeData(){
        this.population += Math.round(this.population * 0.02);
    }
}

class World{
    countries = [];
    copyData = [];

    constructor(){
        this.loadData();
        this.copyData = this.countries.slice(0);
    }

    // Rest of the JavaScript code omitted for brevity

I tried different methods to create the copy array like using spread operator, Array.from(), or Object.assign(), but none of them worked as expected and resulted in unexpected changes to the initial array or NaN values after calculations.

Answer â„–1

When working with JavaScript, objects are copied using reference. So, if you use .slice(0), you are correct in part, but the issue arises when internal values are objects, resulting in the new array retaining previous values.

Another approach is to try .map(obj => ({ ...obj }) ), however, this method will not work as object spread only creates a new object with properties, excluding methods like changeData. To address this, you must implement a copy mechanism for your class.

An updated solution could be:

cloneObject() {
  const {name, area, population} = this;
  return new Country(name, area, population)
}

...

this.copyData = this.countries.map( (obj) => obj.cloneObject() );

Note: You can enhance the functionality of this function by adding an argument to override values, enabling multiple operations in one go:

cloneObject( overrides ) {
  const { name, area, population } = { ...this, ...overrides };
  return new Country(name, area, population)
}

...

this.copyData = this.countries.map( (obj) => obj.cloneObject({ name: 'Hello World' }) );

Sample Code:

class Country{
    name; area; population;

    constructor(name, area, population){
        this.name = name;
        this.area = area;
        this.population = population;
    }
    
    cloneObject() {
      const {name, area, population} = this;
      return new Country(name, area, population)
    }

    changeData(){
        this.population += Math.round(this.population * 0.02);
    }
}

class World{
    countries = [];
    copyData = [];

    constructor(){
        this.loadData();
        this.copyData = this.countries.map( (obj) => obj.cloneObject() );
    }

    loadData(){
        this.countries.push(new Country("Denmark", 41990, 5839809));
        this.countries.push(new Country("Germany", 349360, 83159604));
        this.countries.push(new Country("Netherlands", 33690, 17342709));
    }

    changeAllCountriesData(){
        this.copyData.forEach(c => {
            c.changeData();
        })
    }
}
console.log("Initial information for the population: 5839809, 83159604, 17342709")
w = new World();
w.changeAllCountriesData();
console.log("countries array:")
console.log(w.countries);
console.log("copyData array:")
console.log(w.copyData);

Answer â„–2

Initially, I intended to leave a comment, but unfortunately, my points are insufficient at the moment.

  1. Within the changeAllCountriesData() function (located inside the World class), there seems to be an attempt to call the changeDate() function, which is a local function within the Country class. I am uncertain if the World class can directly access the local functions of another class. You can only invoke a function inside a class after assigning that class to a variable using var, let, or const.

    For example:

    const codeland = new Country('USA', 123, 456);

    codeland.changeData();

At this point, `codeland` becomes a global variable. This allows you to access the `changeData()` function through the `codeland` variable in your `World` class.

While I may not be an expert in JavaScript, I believe there might be a simpler solution!

In terms of copying arrays, methods #1 and #3 appear correct. (I'm unsure about methods #2 and #4. Method #5 involves concatenating the `countries` array with `copyData`.) The reason for returning NaN is that both `countries` and `copyData` are empty when data is being copied from one array to another. Hence, the result is NaN (or undefined).

I trust this explanation proves helpful!

Answer â„–3

To accomplish this task, utilize the Array.prototype.map() method along with object spreading.

const arr = [{ a: 1 }, { b: 2 }];

const newArr = arr.map((singleObject) => {
  return { ...singleObject };
});

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

What is the best way to display a Nested JSON structure without an object key?

Need help with extracting data from two different JSON structures. The first one is straightforward, but the second is nested in multiple arrays. How can I access the content? See below for the code snippets: // First JSON { "allSuSa": [ { ...

Using an image tag with dual quotes in Vue.js

I am currently working on a feature where users can upload an image and then have it displayed after the upload is complete. However, I am facing an issue where the response link of the image contains a double quote, and when I use the <img> tag to ...

Changing the name of a specific attribute in a JSON Object for showcasing it in an HTML Table

Suppose I have fetched a list of objects from a database: [{ "id":0 ,"name":"John", "lastname":"Shell" },{ "id":1,...]; and want to display this data using the dynatable plugin: data : JSON.stringify(data) success: function(data,status){ $( ...

Ways to stop VoiceOver from selecting the background content when a modal is open

Is there a way to prevent VoiceOver from reading the content behind a modal? I tried using aria-modal=true, but it seems VoiceOver does not support this feature by default like NVDA and JAWS do. I found more information about this on . According to the in ...

Issue with Vue template not displaying within a loop

After completing a basic Vue tutorial on setting up a Todo app, I decided to integrate some aspects of it into a website I am developing. However, I have encountered an issue with my for-loop that is not functioning as expected. The project was initially ...

Guide on obtaining the Parent hierarchy within the Tree View component

Hello! I am working with a tree object that has parent and nested children, displayed with checkboxes. When a child is checked, I need to retrieve the names of the parent and grandparent up to the entire hierarchy. Below is my JSON data: { [ ...

Issue: Child Pages not found in Nuxt RoutingDescription: When navigating

Currently working on a Nuxt application that utilizes the WordPress REST API to fetch content. While my other routes are functioning correctly, I am facing challenges with nested pages. The structure I have implemented in my Nuxt app is as follows: pages ...

What steps should I follow to recreate this PHP hashing method in Node.js?

I am currently trying to replicate a password hashing algorithm in node.js (using LTS version 14.x) that was initially coded in PHP (version 7.2). Despite my efforts, the node.js implementation I have created seems to deviate from the original after the fi ...

Basic exam but located in a place that is not valid

Here is a test I am working on: // import {by, element, browser} from "protractor"; describe('intro', () => { beforeEach(() => { browser.get(''); }); it('should have multiple pages', () => { let buttonOn ...

Error message: Uncaught TypeError - The function 'send' is not recognized in the Ajax new Request

When I called my ajax function, I encountered the following error: Uncaught TypeError: ajaxGetData.send is not a function Here is my code: <button onclick="myFunc()" class="btn btn-default">Click</button> <div id="getRes"></div> ...

I am encountering difficulties displaying the image and CSS files from another folder in my HTML with Node.js

I am facing difficulty in establishing a connection between my front-end and back-end using node.js. As a result, the website only displays the HTML code without linking to the CSS or image files. Here is the folder structure: root -src •pi ...

What is the best way to personalize the Window.Confirm() dialog in JavaScript?

var val= confirm("Are you sure to cancel?"); The code snippet above will display a popup with two choices - Ok and Cancel, with Ok being the default choice. Is there a way to make Cancel the default choice instead and switch the positions of the ...

What could be the reason for req.route displaying the previous route instead of

Question: const router = express.Router(); router .route('/:id') .delete( validate(messageValidator.deleteById), MessageController.deleteById, ) .get( validate(messageValidator.getById), MessageController.getById, ); ...

Express encountered an issue when trying to upload a file through AngularJS

I am currently facing an issue with uploading a file to express and subsequently to mongoDB. Despite my efforts, when I attempt to upload the file to express, it appears that no data is being passed through the response. I am utilizing ng-file-upload.min. ...

Ajax modal login feature refuses to close

Struggling to close a modal login box? Everything seems to be functioning correctly with the modal screen and ajax features, but I'm facing issues when it comes to closing the modal form. The code snippet looks like this: HTML: <a href="#" cla ...

Retain the dashes in their original positions while extracting numbers following each dash from an array using Regex

Someone from a different discussion helped me figure out how to extract the numbers from an array. However, I am now struggling to capture the numbers after the "-" dash. Let me illustrate what I have and put you in the same scenario. Here is the array co ...

The custom component I created seems to be unaffected by the inline styles in React

Having an issue with a custom component where I am trying to add margin-top in one of my uses. I attempted using <MyComponent style={{ marginTop: '10px' }}> and also const myStyle = { marginTop: '10px' }; `<MyComponent style= ...

Assigning controller variables within an ajax request

I'm new to AngularJS and I have a question about controller attributes. I've created an attribute called 'anuncio', which contains an array of objects as shown below: var anuncioModule = angular.module('anuncioModule',[]); a ...

Issue with importing Node module (@pusher/push-notifications-web) occurring when page is refreshed in Next.js

Encountering a problem while trying to integrate the node module @pusher/push-notifications-web. More information can be found at https://github.com/pusher/push-notifications-web I'm unsure whether this issue is related to Next.js or the node module ...

Multiple button clicks causing events to fire repeatedly

My PHP file echoes a button, but when I click it, the action fires multiple times. Why is it behaving like this? I have tried solutions from Stack Overflow, but none of them seem to work. Any suggestions or corrections? $(document).on('click',& ...