What is the proper way to implement a $scope.$watch for a two-dimensional array in AngularJS?

Having trouble implementing an Angular watch on a multidimensional array

I've got a screen where users can see two teams (outer array) with team sheets (inner array) for each team. They can drag and drop players to change the batting order.

The batting order gets updated based on the player's position in the array.

The current solution is more of a temporary fix, but it does resolve the immediate issue.

A better solution would be greatly appreciated. Below is the code snippet from my controller:

    $scope.$watch(
        "Teams[0].TeamSheet",
        function (newValue, oldValue) {
            for (var i = 0; i < newValue.length; i++) {
                newValue[i].battingOrder = i + 1;
            }
        },
        true
    );

    $scope.$watch(
        "Teams[1].TeamSheet",
        function (newValue, oldValue) {
            for (var i = 0; i < newValue.length; i++) {
                newValue[i].battingOrder = i + 1;
            }
        },
        true
    );

    $scope.Teams = [{
        TeamName: "South-Africa",
        TeamSheet: [
        {
            name: "A Peterson",
            battingOrder: 1,
            mode: "view"
        },
        {
            name: "Riley Rossouw",
            battingOrder: 2,
            mode: "view"
        },
        {
            name: "H Amla",
            battingOrder: 3,
            mode: "view"
        },
        {
            name: "F Du Plessis",
            battingOrder: 4,
            mode: "view"
        },
        {
            name: "AB De Villiers",
            battingOrder: 5,
            mode: "view"
        }
        ]
    },

     {
         TeamName: "Australia",
         TeamSheet: [
         {
             name: "D Warner",
             battingOrder: 1,
             mode: "view"
         },
         {
             name: "S Watson",
             battingOrder: 2,
             mode: "view"
         },
         {
             name: "M Clarke",
             battingOrder: 3,
             mode: "view"
         },
         {
             name: "C Rogers",
             battingOrder: 4,
             mode: "view"
         },
         {
             name: "S Smith",
             battingOrder: 5,
             mode: "view"
         }
         ]
     }];

Answer №1

If you want to update the batting order directly within the view, you can try the following approach:

<div ng-repeat="member in team" ng-init="member.battingOrder = $index"> 
</div>

By doing this, there is no need to use $watch.

UPDATE

The previous solution may not work correctly if you swap items in your array. To solve this issue, you can use the code below:

  <body ng-controller="MainCtrl">
    <div ng-repeat="member in team">
      {{setIndex(member,$index)}}
      {{member.name}},{{member.index}}
    </div>
    <button ng-click="swap()">swap first with last</button>
  </body>

Controller:

app.controller('MainCtrl', function($scope) {
  $scope.team = [ { index: 0, name : 'first' }, { index: 0, name : 'second' }, { index: 0, name : 'third' } ];
  $scope.swap = function () {
    var tmp = $scope.team[0];
    $scope.team[0] = $scope.team[2];
    $scope.team[2] = tmp;
  }

  $scope.setIndex = function (member, index)
  {
    member.index = index;
  }

});

http://plnkr.co/edit/V3ixkww7dxcx8uZ7f0hj?p=preview

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 element type 'ReactElement<any>' does not match a JSX element constructor function. 'undefined' cannot be assigned to type 'Element | null'

After attempting the suggested fix of deleting node_modules/ and yarn.lock, then reinstalling everything, I still cannot resolve the issue. I am currently developing a basic router that renders children based on a certain prop: import React, { Fragment } ...

Can a component be triggered using ng-click in Angular?

Before, I had a <div> that I was toggling its contents with ng-click. Now, with Angular 1.5 components, I moved the <div>'s content and created a new component. My goal now is to load this component on ng-click. Is this achievable? So fa ...

Please ensure that all fields in the form are filled out before clicking the enable button

Is it possible to enable the button only when all fields are filled out in a form? It's easy if there's just one field, but I have multiple fields with a select field as well. I'm not sure how to do this. Here's the form I've creat ...

Dealing with $broadcast and $on in AngularJS for a specific instance of a controller

My application features a utility controller designed to manage document attachments for reuse. <div ng-controller="someController"> <div ng-controller="documentController as temp1"></div> <div ng-controller="docum ...

Is there a way to troubleshoot why new data is not appending to existing data in React's infinite scroll feature?

I'm currently working on implementing react infinite scrolling for the first time. I've encountered an issue where the initial array of data keeps repeating. function Details() { const [facility, setFacility] = useState([]); const [loading, set ...

Navigating through different sections of a website using AngularJS routing based on ng-view located

Recently, I started delving into Angular and experimenting with setting up basic routing. On my landing page (currently named index2.html), I have included some .js and .css files, as well as a div with <ng-view></ng-view> to display my content ...

Sharing specific props with deeply nested components in React

I am experimenting with configuring props for children components. In this example, I am testing a function to target any child, whether nested or not, with the prop swipeMe. It works perfectly when the render function contains only a single child, like ...

Blending ng-repeat with AngularJS for seamless iteration

Is there a way to achieve a mixed output from two ng-repeats? Current output: john maria peter red blue green Desired output: john red maria blue peter green This is the code: <body ng-controller="MainCtrl"> <div ng-repeat='item in ...

Is it possible that .focus() does not function on a duplicated object?

Greetings to all! I have created a form with rows of input text fields. Users can add as many rows as needed by clicking the 'add row' button. The functionality to clone() for adding rows is working perfectly. In each row, an input field can o ...

Experiencing difficulties loading Expo Vector Icons in Nextjs

I've spent countless hours trying various methods to accomplish this task, but unfortunately, I have had no luck so far. My goal is to utilize the Solito Nativebase Universal Typescript repository for this purpose: https://github.com/GeekyAnts/nativ ...

.post method reveals parameter in URL upon submission

Currently, I am utilizing the $.post method to send a value to a PHP page for processing after replacing the serialize utility with a more specific element: $("button").click(function(event) { $.post( "php/index.php", { seq: $("seq").v ...

Transmission of JSON to a C# controller via AJAX results in a Count value of zero in .NET 7

Whenever I attempt to send a JSON object to my controller, the parameter isn't being received. This is the JavaScript code snippet: var input = document.getElementById("input"); input.addEventListener('change', function () { const read ...

After transitioning my Image Modal from an ID to a Class, it appears to not be functioning properly

I recently implemented an image modal on my website using the ID attribute, but it didn't seem to work as expected. After changing the id to a class, now the image modal is not functioning at all and I'm struggling to figure out what went wrong. ...

Unable to inject basic service into component

Despite all my efforts, I am struggling to inject a simple service into an Angular2 component. Everything is transpiling correctly, but I keep encountering this error: EXCEPTION: TypeError: Cannot read property 'getSurveyItem' of undefined Even ...

Looking for an uncomplicated SSO system similar to Google Identity Toolkit but with a customizable UI interface?

I'm really impressed with the Google Identity Toolkit, it's so user-friendly and easy to set up! However, I'm having trouble with the fact that it forces me to use its UI. Is there another option available that will allow visitors to simply ...

Is it possible to transform an array of objects into a new array of objects?

After searching for a similar question, I realized none of them really addressed my issue... EDIT: My main goal is to create a reusable dropdown component where I can pass items as props directly. These items need to be objects with both a key (for the fi ...

Is it feasible to utilize the translate function twice on a single element?

Using Javascript, I successfully translated a circle from the center of the canvas to the upper left. Now, my aim is to create a function that randomly selects coordinates within the canvas and translates the object accordingly. However, I'm encounter ...

Connect ngModel to an AngularJS directive using a dedicated scope

In an attempt to develop a unique Angular directive that displays radio inputs along with their corresponding labels, the HTML structure for this directive is as follows: <d-radio name="gender" value="male" label="I'm a male"></d-radio> & ...

Managing ng-show in AngularJS outside the ng-repeat loop

Currently, I am diving into the world of Angular and experimenting with toggling the visibility of content div based on clicks on side menu items. <div id="side-menu"> <h3>Side Menu</h3> <div ng-repeat="item in example"> &l ...

The Chrome extension takes control of the new tab feature by redirecting it to a custom newtab.html

I have a website https://example.com where users can adjust their site preferences, including enabling night mode. To enhance the user experience, I developed a Chrome extension for https://example.com that transforms Chrome's new tab with a custom ne ...