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

Node.js request.url is returning incomplete URL

I am currently testing out the code snippet provided in a beginner's book on Node.js. var http = require("http"); var url = require("url"); function onRequest(request, response) { console.log("request URL is: " + request.url); var pathName ...

How to troubleshoot passing json data from a controller to an AngularJS directive

I recently started learning AngularJS and I'm facing an issue with passing JSON data from the controller to a directive. When I try to display the data, nothing shows up and I encounter the following errors: 1. Uncaught SyntaxError: Unexpected token ...

Verify if the button is assigned a specific class, then generate a 'completed' div

I'm new to working with Jquery and I have a question. In my upload form, when something is uploaded the upload-button changes class from: <a class="upload-button upload buy" id="upload-button"><span>Upload a document</span></a> ...

Manipulating div position interactively with vanilla javascript during scroll

I'm trying to create an effect where an image inside a div moves vertically downwards as the user scrolls, stopping only at the end of the page. I've attempted a solution using a script from another post, but it doesn't seem to be working. ...

What are the steps to get started with AngularJS 2?

When starting an Angular 1.XX project, we typically use the following code to bootstrap: ng-app ="myApp" Then in our Javascript file, we set up our app like so: var app = angular.module('myApp',[]); But how do we go about bootstrapping in Ang ...

Material UI - Array of Chips

I have been working on creating a ReactJS component that displays an array of chips with unique styling for each one. To achieve this, I created individual makeStyles classes for the chips. However, I encountered difficulties in dynamically changing the cl ...

Is there a way to incorporate a text box in javascript that displays the retrieved reference count from the database?

I'm currently working on creating a functionality that retrieves rows with the same ID from a database and displays them in a text box. Below is the PHP code I've written for retrieving all the rows: PHP: <?php include_once('pConfig ...

Using Javascript to fetch JSON data from a PHP file hosted on an IIS server, incorporating JSONP with

I have set up an HTML5, JavaScript, and CSS3 https application on Windows IIS (Internet Information Services). The structure of the root directory is as follows: index.html, src/index.js, src/send_payment.php Currently, I am attempting to retrieve a basi ...

Using Jquery Chosen Plugin to Dynamically Populate One Chosen Selection Based on Another

Good evening to all, please excuse any errors in my English. I have successfully integrated a jQuery Chosen plugin with my 'estado' field (or province). My goal is to populate another jQuery Chosen plugin with the cities corresponding to that s ...

Exiting callback function in JavaScript

Is there a way to retrieve the return value from within a node.js/javascript callback function? function get_logs(){ User_Log.findOne({userId:req.user._id}, function(err, userlogs){ if(err) throw err; if(userlogs){ ...

Preventing undesired form submissions in HTML and JavaScript

My question might be simple, but it's what I have in mind. When working with two buttons in HTML - one for form submission and the other to trigger a JavaScript event - both buttons end up submitting the form. How can I make sure the second button onl ...

Issue with $observe in AngularJS

Unable to trigger the $observe function on change. .directive('watchContent', function () { return { restrict: 'A', link: function (scope, elem, attrs) { console.log(attrs.class) attrs.$observe("class", functi ...

How can I dynamically populate my select field with JSON data using React.js?

My goal is to fetch data from an API and use the 'symbol' JSON field as options for a select dropdown. However, I'm encountering an issue: 'TypeError: Cannot read property 'length' of undefined.' Beneath my code, I' ...

Show ng-message when email is invalid in Angular Material without using ng-pattern

I need to show an error message that says Please enter valid email. when an invalid email is entered, but I cannot use the ng-pattern attribute with this specific regex pattern. <md-input-container class="md-block" flex-gt-xs> <label>Ema ...

Utilize React Material UI to dynamically update state with Slider interactions

Currently, I am in the process of developing a multi-step form (survey) using React.js and the Material-UI components library. However, I have encountered an issue with the slider component at one of the steps – it does not seem to update the state as ex ...

I encountered an issue where the error "data.map is not a function" occurs whenever I try to execute a React component

I have implemented the HorizontalScrollbar component and passed data as a prop. When I try to run the HorizontalScrollbar component, I encounter the following error in the console tab of Chrome: Error: Uncaught TypeError: data.map is not a function Horiz ...

How can you create a personalized sorting order using odata?

Within my AngularApp, I retrieve data from a WebAPI using OData queries. All the retrieved results contain both a date and an integer status code. The status codes range from 1 to 4. I am aiming to organize my results in such a way that all items with a ...

Incorporate audio playback on image click using JavaScript, with the feature to automatically pause the playback if multiple images are playing simultaneously

<img class="cl" src="photo/198.jpg"/></br> <audio class="cs" controls> <source src="audio/198 banu nagamothu.mp3" type="audio/mpeg"> </audio> I prefer not to have audio controls initially, but when the image i ...

Searching and Substituting Elements with jQuery in a Text String

After making an Ajax call, I have retrieved HTML as a string. headings .... <div class="wrapper"> <input type="text" name="email" value="" /> </div> .... I have extracted the .wrapper and input elements from the HTML string. var el ...

How to redefine TypeScript module export definitions

I recently installed a plugin that comes with type definitions. declare module 'autobind-decorator' { const autobind: ClassDecorator & MethodDecorator; export default autobind; } However, I realized that the type definition was incorrec ...