Applying a value to all JSON objects within an array using AngularJS and JavaScript

Tale:
I've developed an array ($scope.mainArray) that will be displayed in a <table> with <tr> elements using ng-repeat as shown below:

+---+
| 1 |
+---+
| 2 |
+---+
| 3 |
+---+

Each object contains an array which is presented within <td> tags using ng-repeat like so:

+---+-----+-----+-----+
| 1 | 1-1 | 1-2 | 1-3 |
+---+-----+-----+-----+
| 2 | 2-1 | 2-2 | 2-3 |
+---+-----+-----+-----+
| 3 | 3-1 | 3-2 | 3-3 |
+---+-----+-----+-----+

Each <td> represents a boolean variable. If it's true, the background color of the <td> turns green; otherwise, it remains default.

Challenge:
Whenever I set one boolean to true, all corresponding <td>'s in that column turn green. The code

$scope.mainArray[0].subArray[0].isGreen = true;
, intended to turn cell 1-1 green, ends up turning both 2-1 and 3-1 green as well.

SSCCE:

Plunker: https://plnkr.co/edit/9q3PMO?p=preview

SO Snippet:

angular.module("App", [])

  .controller("Controller", function($scope) {
    var initSubArray = function() {
      var data = [{
        "value": 1,
        "label": 1,
        "isGreen": false
      }, {
        "value": 2,
        "label": 2,
        "isGreen": false
      }, {
        "value": 3,
        "label": 3,
        "isGreen": false
      }];

      return data;
    };

    var initMainArray = function() {
      var data = [{
        "value": 1,
        "label": 1
      }, {
        "value": 2,
        "label": 2
      }, {
        "value": 3,
        "label": 3
      }];

      return data;
    };

    var putSubArray = function() {
      var subArray = initSubArray();
      for (i = 0; i < $scope.mainArray.length; i++) {
        $scope.mainArray[i].subArray = subArray;
      }
    };

    $scope.init = function() {
      $scope.mainArray = initMainArray();
      putSubArray();
      $scope.mainArray[0].subArray[0].isGreen = true;
    };
  });
table {
  border-collapse: collapse;
}

td {
  border: solid;
}

.green {
  background-color: #00FF00;
}
<!DOCTYPE html>
<html>

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script>
</head>

<body ng-app="App" ng-controller="Controller" ng-init="init()">
  <table>
    <tr ng-repeat="foo in mainArray">
      <td>
        {{foo.label}}
      </td>
      <td ng-repeat="bar in foo.subArray" ng-class="{'green' : bar.isGreen}">
        {{foo.label}}-{{bar.label}}
      </td>
    </tr>
  </table>
</body>

</html>

Answer №1

To update the following function, search for the code snippet below. We have also included angular.copy to prevent any referencing issues.
Preview

var updateSubArray = function() {
    var subArray = generateSubArray();
    for(j = 0; j < $scope.mainList.length; j++ ) {
        $scope.mainList[j].subArray = angular.copy(subArray);
    }
};

Answer №2

The issue arises from having only one subArray object with three references. Any changes made affect all the rows using this subArray.

To resolve this, consider modifying the following code:

var putSubArray = function() {
    var subArray = initSubArray();
    for (i = 0; i < $scope.mainArray.length; i++) {
        $scope.mainArray[i].subArray = subArray;
    }
};

to something like:

var putSubArray = function() {
   for (i = 0; i < $scope.mainArray.length; i++) {
       var subArray = initSubArray();
       $scope.mainArray[i].subArray = subArray;
   }
};
 

or a neater alternative to the above suggestions.

Answer №3

One issue arises when you reference your subArray object within mainArray. This results in any changes made to the subArray affecting the original object.

To prevent this, I suggest using the angular.copy function in your putSubArray function:

var putSubArray = function() {
    var subArray = initSubArray();
    for(i = 0; i < $scope.mainArray.length; i++ ) {
        $scope.mainArray[i].subArray = angular.copy(subArray);
    }
};

Additionally, I have updated your Plunker.

For a more detailed explanation, you can refer to this link.

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

Function in Typescript that accepts either a single object or an array of objects

We frequently use a simple function declaration where the function can accept either a single object or an array of objects of a certain type. The basic declaration looks like this: interface ISomeInterface { name: string; } class SomeClass { pu ...

The touch events are not detected on Pixi.js when buttons are placed on a stage that has been both scaled and

Currently, I am developing a game using pixi js. In order to ensure that the game appears consistent on all screens, I have implemented the following scaling logic: this.scale = Math.max(this.viewWidth, this.viewHeight) / (2048 * this.ratio); Additionall ...

Executing a <SCRIPT> within an Ajax-loaded webpage

Utilizing Framework7 for my web application has been great since it allows me to load pages using Ajax, giving it an app-like feel. However, I am facing a challenge with making the "ad" code display properly on Ajax-loaded pages. If you inspect the ad co ...

What are the advantages of using the CRUD coding style with Redux?

Seeking guidance on the best coding style for a single page application regarding the use of React Redux For instance, consider a standard CRUD page where data is presented in a table with a pop-up modal form. The table's data comes from server-side ...

Ways to loop through an array of daytime values and exhibit just the records for the current week

ng-repeat="day in task.DailyWorks | limitTo : weekdays.length: weekStart" This iteration process enables me to showcase the daily work records in a structured format within the table columns. The feature allows for seamless navigation between different we ...

Adjust the positioning of a class element

I have an eye icon that changes position when clicked. Initially, it is set to left: 10%;, but if there is a DOM element with the ID login-section, it should be repositioned to left: 50%;. I attempted to use document.getElementsByClassName('fa-eye-sl ...

Encountering a "Text creation error" while trying to run a three.js demo on Microsoft Edge using the WebGL context

When attempting to run three.js on Edge, an error message appears stating 'text could not be created. Reason: Could not create a WebGL context.' Even after trying to execute the official three.js example on Edge, the same error persisted, while ...

What is the method to allocate the smallest available number that has not yet been assigned?

As I'm dynamically generating elements and adding them to the page, each element needs a unique numerical id. However, due to non-linear removal of elements, there can be gaps in the assigned ids. For example... In one scenario: 1, 3, 4, 5, 16, 22. ...

Modify the state from a listener that is enclosed in the useEffect function

Within my hook called useQueryEvents, I have a setup that involves fetching all past transactions for a user and listening to the network for incoming/outgoing transactions. These transactions are then passed into a function called addActionToActivity, whi ...

Tips for incorporating a CSS transition when closing a details tag:

After reviewing these two questions: How To Add CSS3 Transition With HTML5 details/summary tag reveal? How to make <'details'> drop down on mouse hover Here's a new question for you! Issue I am trying to create an animation when t ...

Instead of showing the data in the variable "ionic", there is a display of "[object object]"

Here is the code snippet I'm working with: this.facebook.login(['email', 'public_profile']).then((response: FacebookLoginResponse) => { this.facebook.api('me?fields=id,name,email,first_name,picture.width(720).height( ...

Before the async function, make sure to set the value using React's useState

Exploring the world of react context api for the very first time. Below is my react code utilizing the context api: const [valChanged, setValChanged] = useState(false); async function modalSave() { await setValChanged(true); // STEP 1 await o ...

Is your Jquery validation malfunctioning?

I am currently facing a challenge with required validation on an asp.net page. In order to validate the inputs, I have implemented multiple controls which can be hidden or displayed based on certain conditions. These controls include checkboxlists, dropdow ...

The Challenge of Referencing Javascript Files (including jQuery)

Previously, I had the following code snippet: <head> <script src="/Scripts/jquery-1.3.2.min.js" type="text/javascript"></script> <script type="text/javascript"> var optPrompt = "- Select One -"; var subCats ...

How can I verify if my discord.js bot has the necessary permissions from a server or channel?

I need to verify two things: Determine if my bot has a particular SERVER permission (return true/false based on the presence of that permission) Confirm if my bot possesses a specific CHANNEL permission (return true/false depending o ...

An undefined variable was encountered within the 'else' statement

I am encountering an issue with my code where it is returning an 'undefined' error. The problem arises when I attempt to remove an id from an array using the variable 'id', but instead, it throws an error stating 'undefined'. ...

$routeProvider is encountering difficulties in retrieving the HTML template

I am facing an issue despite adding both angular.min.js and angular-route.min.js files. Here is the code in app.js: var myApp = angular.module('myApp',[ 'ngRoute', 'artistControllers' ]); myApp.config(['$routeProvider& ...

Mapping drop-downs based on the length of a JSON array

Looking to generate dropdowns in a React Native mobile application based on the length of values in an API JSON array. Here's an example of the desired output: eg:- Choice 1 (Label of the Drop Down) -Sub Choice 1 . (Value Data) ...

Optimizing shadow rendering in Three.js for top-notch performance

I've been working on a Minecraft project using Three.js, but I've run into some performance issues specifically when rendering shadows. If you'd like to check out the demo, you can find it here: You'll notice that the FPS drops below ...

The chosen option does not equal the value retrieved by using jQuery's

I am perplexed by the situation at hand. It seems that there is a discrepancy in the selected option of my select element. Despite appearing as the empty default option on top, the inspected element reveals it displaying a value of 13. https://i.sstatic.n ...