The gridOptions.$gridScope.columns in ng-grid is modified two times when hiding or showing columns

Question:

Why does the $scope.$watch function get called twice when I manually hide/show a column but only once when I reorder/sort columns in ng-grid?

When I specifically target a single column with the watch function, it is only called once. I suspect that on hide/show actions, the entire ng-grid is changed, while on reorder/sort, only specific columns are affected.

Is there a way to determine which events trigger the function call in each situation?

Another Question:

How can I prevent the second or first invocation of the function?


I attempted to debug certain sections of AngularJS code:

if ((watchers = current.$$watchers)) {
    // process our watches
    length = watchers.length;
...
watch.fn(value, ((last === initWatchVal) ? value : last), current);
...
// in the case user pass string, we need to compile it, do we really need this ?
if (!isFunction(listener)) {
    var listenFn = compileToFn(listener || noop, 'listener');
    watcher.fn = function(newVal, oldVal, scope) {listenFn(scope);};
}

I noticed that watchers[4] and watchers[5] have identical expressions (gridOptions.$gridScope.columns), but watchers[5] has my function as its action while watchers[4] calls listenFn(scope).

My attempt to use $gridScope.renderedColumns resulted in the same issue.

Answer №1

After some experimentation, I have come up with a solution that avoids altering the ng-grid and AngularJS code:

var counter = 0;
$scope.$watch('gridOptions.$gridScope.columns', updateFunction, true);
function updateFunction(newValues, oldValues){
    if ( oldValues !== newValues && oldValues.length === newValues.length ) {
        if ( areColumnsEqual(oldValues, newValues) || isReordered(oldValues, newValues) ) {
            console.log('\n\n=====  ' + (counter++) + ' =====');
        }
    }
}

function isReordered(oldValues, newValues) {
    for ( var i = 0 ; i < oldValues.length ; i++ ) {
        if ( oldValues[i].originalIndex !== newValues[i].originalIndex ) {
            return true;
        }
    }
    return false;
}

function areColumnsEqual(oldValues, newValues) {
    for ( var i = 0 ; i < oldValues.length ; i++ ) {
        if ( oldValues[i].width !== newValues[i].width ) {
            return false;
        }
    }
    return true;
}

Now the console.log function is triggered only once for every resize, hide, show, reorder, or sort operation.


If you want to respond specifically to actions like reordering, showing, or hiding columns:

var counter = 0;
$scope.$watch('gridOptions.$gridScope.columns', columnChangeFunction, true);

function columnChangeFunction(newValues, oldValues){
    if ( oldValues !== newValues && oldValues.length === newValues.length ) {
        if ( isHideOrShowAction(oldValues, newValues) || isReordered(oldValues, newValues) ) {
            console.log('\n\n=====  ' + (counter++) + ' =====');
        }
    }
}

function isReordered(oldValues, newValues) {
    for ( var i = 0 ; i < oldValues.length ; i++ ) {
        if ( oldValues[i].originalIndex !== newValues[i].originalIndex ) {
            return true;
        }
    }
    return false;
}

function isHideOrShowAction(oldValues, newValues) {
    for ( var i = 0 ; i < oldValues.length ; i++ ) {
        if ( oldValues[i].visible !== newValues[i].visible ) {
            return true;
        }
    }
    return false;
}

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

Observing the state of a variable within a directive using a service from a different module

I currently have two modules named "core" and "ui". The "ui" module has a dependency on the "core" module. Below is the code for my core.js file: var core = angular.module('core', [ 'ngRoute' ]); // Services core.service('httpI ...

Verify the occurrence of a search result and if it appears more than once, only show it once using JavaScript

Hello all. Currently, I am developing an online users script using NodeJS and SocketIO. The functionality works fine, however, I am encountering an issue where if a user connects from multiple browsers, windows, or devices, it displays duplicate results li ...

Does AngularJS have a similar function to $(document).ajaxSuccess()?

When working with AngularJS, I am looking to implement a universal ajax loader that does not require integration into each controller to function. In jQuery, this can be achieved through the following code: (function globalAjaxLoader($){ "use strict"; ...

Encountering a parse error when making an AJAX call using structural functions

I'm in the process of developing an API and here is my PHP function. function retrieve_schools($cn){ $schools_query = "SELECT * FROM schools"; $school_result = mysqli_query($cn, $schools_query); $response_array['form_data'][&apo ...

What is the best way to transfer an element and all its children to another div without losing any jQuery functionality?

At first, sharing an example of the JavaScript and HTML from my page is challenging because I couldn't make it work on JSfiddle. The issue I'm facing involves jQuery on a page where I've created two tabs. Essentially, it's the same con ...

Angular JS has a unique feature of a scrollable drop-up menu that allows

Here is the code snippet for my Dropup component: <div class="dropup"> <button class="btn btn-primary btn-raised dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false> ...

KnockoutJS's data binding feature is failing to display any content within the table rows

My JavaScript function creates a model and applies it to an HTML document using knockoutJS. In the HTML file, I have two different ways of displaying the same data: 1- A select list (which is working fine) 2- A table (not showing the same data) I need a ...

How can I place an Object in front of an Array in JavaScript?

Currently, I am working on an Angular project where I need to modify a JSON array in order to display it as a tree structure. To achieve this, the objects in the array must be nested within another object. Desired format / output: this.nodes = [ { id ...

The JavaScript program is occasionally receiving unconventional input

I'm really struggling with this one. As part of a programming exercise, I am developing a JavaScript calculator. You can access the functioning calculator here on Codepen. At the bottom left corner of the calculator interface, you will notice a "+-" ...

Enhancing React Flow to provide updated selection and hover functionality

After diving into react flow, I found it to be quite user-friendly. However, I've hit a roadblock while attempting to update the styles of a selected node. My current workaround involves using useState to modify the style object for a specific Id. Is ...

Move router parameters to separate files to streamline and organize code

I have encountered a bit of an issue. I currently have the following code in my routing.js file where I define both my parameter and route. I have moved the routes to a separate router instance in my routing.js file, but I am struggling to separate the par ...

A collection of collections

Alright, listen up. I've got a JSON file with an array inside another array. Here's a snippet of the JSON file: { "keys": [ { "game": "Counter-Strike: Global Offensive", "price": "5", "listofkeys" ...

Creating a React.js component and setting an initial value within it

Recently delved into the world of React.js and currently attempting to create a reusable header that can switch between two states: one for when the user is logged in, and another for when the user is not logged in. // Header.js var Header = React.createC ...

Mentioning VARs found on additional pages

I'm currently designing a website. At the moment, I have set up the site to prompt users for their name on the landing page and store it in a string variable. var username = ""; Once users enter their name and click "Enter Site," they are directed ...

Tips on transferring information from Angular to Rails

I am quite new to Angular, having only started learning it a week ago. My query pertains to how data can be transferred from Angular to Rails. Essentially, I wish to store whatever is input into {{entry.name}} in Rails. Appreciate your assistance! & ...

Show only specific data from JSON results

I am trying to display a specific cryptocurrency's price without the need for curly braces or explicitly stating "USD". Currently, it appears as {"USD":0.4823} when using the following code: <script> $(document).ready(function () { ...

Is it possible to automate a query to an API through PHP and store the results on a local drive?

Recently, I created a webpage that fetches data from an API. However, the response time from the server is quite slow, taking around 10-20 seconds to retrieve the information. To mitigate cross-domain issues, I have set up a PHP proxy for the JavaScript re ...

Top recommendations for implementing private/authentication routes in NextJS 13

When working with routes affected by a user's authentication status in NextJS 13, what is the most effective approach? I have two specific scenarios that I'm unsure about implementing: What is the best method for redirecting an unauthenticated ...

redirecting from an AJAX request

Seeking a way to perform a redirect following an ajax `put` request. My intention is to implement client-side validation using pure JS. Client: $(document).ready(function() { login = () => { var username = $("[name='username']"). ...

Using React and Material-UI: Implementing button functionality to call another class using hooks in the main App component

Just starting out with React/MUI and currently working on different components for a website, so the UI is not a priority at the moment. Encountering an issue when trying to create a button that links to the Sign Up page (similarly for Sign In): Error: ...