Adding data from one object to another in Javascript results in duplicated entries

Despite my efforts to find a solution for my issue, I couldn't locate a relevant topic. Being new to Javascript, I suspect my lack of understanding is hindering me from resolving the problem. After days of trying, I'm still unable to grasp it. Any help would be greatly appreciated - thank you.

Issue: I am attempting to map data from a JSON object retrieved from an API (Source) to a different data structure (Result). Strangely, duplicates are being generated in my assignment, even though I believe I am explicitly assigning to only one position in the data object.

I apologize for the lengthy code example, but the problem lies at the very end of it. In the debugger, I can observe that in each iteration of the loop, all values are assigned to all result series.data - despite not understanding why.

Below is my code:


function Sample(){

    // Source data from the API simplified
    var SourceData = {
        "hits": 4,
        "job": [
            {
                "status": "FINISHED",
                "type": "IMPORT",
            },
            {
                "status": "FAILED",
                "type": "EXPORT",
            },
            {
                "status": "RUNNING",
                "type": "TRANSCODE",
            },
            {
                "status": "FINISHED",
                "type": "TRANSCODE",
            }
        ]
    };

    // Helper variable
    var status = [];


    //Initialize Result data object
    var ResultData = {
    labels: [],
    series: []
    };

    // Used to to extend the Result Data Object later
    var placeholderSeries = {name:'', data: []}

    // Get job types and Status from SourceData and write as labels and series.name to result object without duplicates 
    for (var i=0; i < SourceData.job.length; i++){

        var typeExists = ResultData.labels.indexOf(SourceData.job[i].type);
        var statusExists = status.indexOf(SourceData.job[i].status);

        if (typeExists == -1){
        ResultData.labels.push(SourceData.job[i].type);
        ResultData.labels.sort();
        }

        if (statusExists == -1){

        // Fill array with Status values without duplicates
        status.push(SourceData.job[i].status);
        // Fill result data with empty sub structure
        ResultData.series.push(placeholderSeries);
        }
    }

  // Write a series name for each job status corresponding with the status values of the source
 for(var i=0; i < ResultData.series.length; i++)
  {
      // THIS LINE DOESN'T WORK AS I WOULD EXPECT
      ResultData.series[i].name = status[i]; 
   }
   console.log(JSON.stringify(ResultData,null,4));
}  

The Outcome I get is:


{
    "labels": [
        "EXPORT",
        "IMPORT",
        "TRANSCODE"
    ],
    "series": [
        {
            "name": "RUNNING",
            "data": []
        },
        {
            "name": "RUNNING",
            "data": []
        },
        {
            "name": "RUNNING",
            "data": []
        }
    ]
}

The Expected Outcome should be:

{
    "labels": [
        "EXPORT",
        "IMPORT",
        "TRANSCODE"
    ],
    "series": [
        {
            "name": "FINISH",
            "data": []
        },
        {
            "name": "FAILED",
            "data": []
        },
        {
            "name": "RUNNING",
            "data": []
        }
    ]
} 

Answer №1

function Sample() {
        // Data obtained from simplified API source
        var SourceData = {
            hits: 4,
            job: [
                {
                    status: "FINISHED",
                    type: "IMPORT"
                },
                {
                    status: "FAILED",
                    type: "EXPORT"
                },
                {
                    status: "RUNNING",
                    type: "TRANSCODE"
                },
                {
                    status: "FINISHED",
                    type: "TRANSCODE"
                }
            ]
        };

        // Helper variable to store unique statuses
        var status = [];

        //Initialize Result data object structure
        var ResultData = {
            labels: [],
            series: []
        };


        // Extract job types and Status from SourceData and organize as labels and series.name in result object without duplicates
        for (var i = 0; i < SourceData.job.length; i++) {
            var typeExists = ResultData.labels.indexOf(SourceData.job[i].type);
            var statusExists = status.indexOf(SourceData.job[i].status);
            
            if (typeExists == -1) {
                ResultData.labels.push(SourceData.job[i].type);
                ResultData.labels.sort();
            }

            if (statusExists == -1) {
                // Populate array with unique Status values
                status.push(SourceData.job[i].status);
                // Build empty sub structure in result data 
                var placeholderSeries = { name: "", data: [] };
                ResultData.series.push(placeholderSeries);
            }
        }

        // Assign a series name for each job status based on the status values from the source
        for (var i = 0; i < ResultData.series.length; i++) {
            // CORRECTION NEEDED HERE
            ResultData.series[i].name = status[i];
        }
        console.log(JSON.stringify(ResultData, null, 4));
    }
    Sample();

You have incorrectly utilized reference type. You have duplicated the same placeholderSeries in the array multiple times, essentially adding the same object.

With reference types, you're not storing the value itself, but rather a reference to it, enabling multiple variables to point to the same value.

For instance:

var x = {"name": "John"};
var y = x;
y.name = "John2";

Both x and y will be affected since they both refer to the same object.

To resolve this issue, move the declaration of placeholderSeries inside the loop. This way, a new object will be created in each iteration.

Answer №2

When working with newer versions of JavaScript, the map function can be utilized in the following manner:

// Here is a simplified example using data from an API
const sourceData = {
    "hits": 4,
    "job": [
        {
            "status": "FINISHED",
            "type": "IMPORT"
        },
        {
            "status": "FAILED",
            "type": "EXPORT"
        },
        {
            "status": "RUNNING",
            "type": "TRANSCODE"
        },
        {
            "status": "FINISHED",
            "type": "TRANSCODE"
        }
    ]
};

const labels = [...new Set(sourceData.job.map(item => item.type))];
const uniqueStatuses = [...new Set(sourceData.job.map(item => item.status))];

const resultData = {
    labels,
    series: uniqueStatuses.map(item =>({"name": item, data: []}))
};

console.log(JSON.stringify(resultData, null, 4));

Answer №3

  • statusExists is always = -1
  • You are constantly using .push(placeholderSeries);
  • placeholderSeries remains the same object each time (
    var placeholderSeries = { name: '', data: [] }
    )

During the final iteration loop:

  // status:  [ 'FINISHED', 'FAILED', 'RUNNING' ]
  for (var i = 0; i < ResultData.series.length; i++) {
    // THIS LINE IS NOT WORKING AS EXPECTED
    ResultData.series[i].name = status[i];
  }

We are assigning the value of a single object to 'RUNNING'

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

The Socket IO Client is receiving a different object than the one that was sent by the Server

My server side code is sending an object to the client side, but the object received by the client is completely different from what was sent. Let me elaborate: Code Server side code: //Setting up the example var response={}; response.models=[]; respo ...

"Create dynamic web pages with multilingual support using HTML, JQuery, and nested

For my multilingual website, I wrote this simple JQuery code: (function() { var language, translate; translate = function(jsdata) { $('[tkey]').each(function(index) { var strTr; strTr = jsdata[$(this).attr('tkey')] ...

Perform multiple function invocations on a single variable using JavaScript

Is there a way to execute multiple functions on a single object in JavaScript? Maybe something like this: element .setHtml('test'), .setColor('green'); Instead of: element.setHtml('test'); element.setColor('gre ...

Using JSON format to pass variables in C# programming language

Is there a way to properly pass my variable within a JSON string like this? string name = "john"; string json = @"{ 'EmployeeName': name, 'EmployeeID': '123', } I ke ...

Can you guide me in utilizing this API endpoint efficiently to enable search functionality using React Query?

const { isLoading, isError, data, error, refetch } = useQuery( "college", async () => { const { result } = await axios( "http://colleges.hipolabs.com/search?name=middle" ); console.log(&quo ...

What steps can be taken to enhance the efficiency of this complex nested asynchronous loop?

The issue at hand involves an array of objects structured like this: let myObj = [ {'db1':['doc1','doc2','doc3']}, {'db2':['doc4','doc5']}, {'db3':['doc7','doc8 ...

Token generated by Sinch backend for use with Javascript and Android applications

I am currently exploring two distinct methods for creating the sinch authentication token on an app server. One approach is designed for the Android client while the other is tailored for the JS client. Is it feasible to utilize the same token for both the ...

The color of the SVG is not visible in the PNG rendition

I have applied a style to an svg image and successfully changed the fill color using a random colors function in JavaScript. However, when I convert the svg to a png format after making these color changes, the PNG file retains the original colors instead ...

Obtain an array from JSON within Azure Data Factory with this simple guide

My current setup, although not functioning properly, consists of two pipelines: Retrieving API data to store in a lake: for each row in the metadata table in SQL, I make a call to the REST API and transfer the response (json files) to the Blob datalake. T ...

What are the steps to integrate TypeScript into JavaScript code?

How can I import a TypeScript class in a Node CommonJS JavaScript file? When using mongoose in my TypeScript code, I typically do the following: // user.model.ts export const UserModel = model<User>('User', schema); In my JavaScript code: ...

What is causing the #reset button to trigger the Flow.reset() function when the #gameboard does not contain any child elements?

Whenever I click on the resetBtn, it triggers the Flow.reset function regardless of whether the gameboard has child elements. Am I using the hasChildNodes() method incorrectly? const resetBtn = document.querySelector('#reset'); resetBtn.addEventL ...

What's the best way to fill checkboxes in EJS when editing a route?

As a beginner, I am working on my first project - a simple content/property listings app. I have created a form to collect user data and display it on a show form. The form includes sections for checkboxes and radio buttons, with the values being stored i ...

Ways to conceal images until AFTER the completion of the jquery flexslider loading process

After trying to integrate wootheme's Flexslider on my website, I encountered a small issue with its loading process. Whenever the page is refreshed with the slider, there is a brief moment (approximately 1 second) where the first slide appears overly ...

Utilize arrays in Java with Selenium WebDriver for optimal performance

I am planning to use arrays for testing Gmail login. One important step in the Gmail login process is verifying the username first. I intend to create an array variable to store multiple usernames. {"#[email protected]","[email protected]","[e ...

Running Handlebars using NodeJS can sometimes result in a "Cannot find module './parser'" error

After successfully creating and implementing a Handlebars template in the Browser, my next goal is to utilize the Handlebars precompiler, which requires a NodeJS module. I have already downloaded Handlebars for NodeJS along with all dependencies locally (n ...

Exploring the possibilities of infinite scroll in JavaScript using the Backbone framework

I've been grappling with this problem for three days straight. I've been attempting to incorporate scrolling into my backbone project using the https://github.com/paulirish/infinite-scroll plugin. Despite my best efforts to find a solution throu ...

How can I set a value using document.getElementById(idPopUPImage).innerHTML to create a static popup in Leaflet?

I added a leaflet map to my project which you can find on Codpen In the map, I've included a button key that displays an image in a popup when clicked. However, after closing the popup and reopening it, the image doesn't show unless I click the ...

Can you tell me the JSONPATH symbol that signifies a mismatch with a regular expression?

My Zabbix item has the PreProcessing JSONPath as shown below: Item key: vfs.fs.get Preprocessing JSONPath script: $.[?(@.fstype =~ '{$FSTYPE.MATCHES}')] The resulting structured JSON list looks like this: [{ "fsname": "/" ...

Generating a JSON object based on the selection of dynamic checkboxes

Hello everyone, I am new to jQuery so please be patient with me as I embark on this journey! My goal is to structure my data in the following format... { "qualifications": [ "1", "7" ], units: [ "7", "3", "1" ] } The HTML looks like ...

Error: Unable to locate module: Material-UI - Please check the path and try again

Encountering this error: Error message: Failed to compile ./node_modules/@material-ui/core/Modal/Modal.js Module not found: Can't resolve '@babel/runtime/helpers/builtin/assertThisInitialized' in 'C:\Users\rifat\ ...