Triggering an event upon completion of ng-repeat's execution

I am facing a challenge in updating the style of a specific element after ng-repeat has finished changing the DOM. The directive I have implemented for triggering ng-repeat works perfectly fine when adding items to the model, but it does not get called when removing an object from the list.

To demonstrate this issue, I have created a function that randomly adds and removes data from the list. You will notice that the removal operation does not trigger the ng-repeat directive call. Is there any way to address this problem?

var module = angular.module('testApp', [])
.directive('onFinishRender', function ($timeout) {
return {
    restrict: 'A',
    link: function (scope, element, attr) {
        if (scope.$last === true) {
            scope.$evalAsync(attr.onFinishRender);
        }
    }
}
});

Fiddle Link

Answer №1

If you want to achieve this functionality:

<div ng-repeat="item in items" on-finish-render="runTest()"
    ng-init="initialize($last, item)">{{item}}</div>
$scope.initialize = function(isLast, element){
    if(isLast)
        console.log(element)
}

ng-init is a directive that triggers when the element is initialized.
$last is a boolean flag set to true if the current element is the last one in an ng-repeat loop.

Check out the updated Fiddle here

Answer №2

Is there a better alternative to using $watch in this situation?

$scope.$watch('ta', function (newVal, oldValue) {
    if(oldValue.length > 0)
    {
        var i = 0; // perform an action
    }
}, true);

This approach allows for more control over when items are added or removed from the array.

Check out this example on JSFiddle

Answer №3

When you add a new item to the list, it automatically triggers its own update() function upon rendering. Remember, each item in the array has its individual onUpdateRender directive with unique properties.

If you need to perform specific actions after changing the length of the list, consider alternatives to using a directive.

Answer №4

An easy and efficient method

<li ng-repeat="data in dataList" ng-init="$last && $parent.myOnFinishHandler();" ></li>

$parent refers to the scope where the datalist is located

angular.module("xyz", []).controller('mc', function($scope) {
  $scope.dataList = ["abc", "123", "xyz", "orange", "apple"];
  $scope.myHandler = function() {
    console.log("render finish ");
  }

});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="xyz">
  <ul ng-controller="mc">
    <li ng-repeat="data in dataList" ng-init="$last && $parent.myHandler();"> {{data}} </li>
  </ul>
</div>

Answer №5

I stumbled upon the answer while browsing through another solution.

It turns out there isn't a straightforward way to achieve this functionality. I ended up creating a filter that essentially does what I need it to do. Here's the basic idea:

app.filter('ngRepeatFinish', function($timeout){
    return function(data, scope){
        //var scope = this;
        var flagProperty = '__finishedRendering__';
        if(!data[flagProperty]){
            Object.defineProperty(
                data, 
                flagProperty, 
                {enumerable:false, configurable:true, writable: false, value:{}});
            $timeout(function(){
                    delete data[flagProperty];                        
                    scope.$emit('ngRepeatFinished');
                },0,false);                
        }
        return data;
    };
})

This filter broadcasts for every element created, allowing me to run my watch function based on the listening event in the controller.

$scope.$on('ngRepeatFinished', function() {
    //Perform some magic here
})

In order to use this directive, I have to pass the scope from the HTML by adding "this" before ngRepeatFinish.

<div ng-repeat="item in (items | ngRepeatFinish:this)"></div>

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

Using Vue.js to handle asynchronous functions with undefined variables

My Vue.js application is facing a problem where an async function is passing a variable as undefined even though it's properly defined before the function call. The async function FETCH_DATA in my Vue.js application is defined like this: async [FETCH ...

I did not anticipate the React setState function to behave in the manner it did

While working on form validation for my page, I came across a tutorial showcasing a validation method that seems to be functioning correctly. However, there is one aspect that I am struggling to grasp. The tutorial suggests declaring a variable before the ...

Is it possible to utilize AJAXToolKit and Jquery on a single webpage?

Is it possible to utilize both AJAXToolKit and jQuery on a single page? For example, let's say we have ScriptManager in the same page along with including ...

Using Next.js Link prefetch feature can lead to unexpected 404 errors on a production website

I'm currently working on a Next.JS blog project where I have created a page to showcase all of my articles. When I render the component, it appears like this: <div> {articles.map((article, index) => { const path = `/magazine/${ar ...

Swap out the string variable when it is modified

To generate a string inside the "code" variable that combines the selected image values, the final code should appear similar to: "test1/A=1a/B=1b" or "test2/A=1b/B=1a", etc. If the user modifies icon "A," it should replace the value in the code instead of ...

DataTables.Net Buttons not appearing in the interface

I have a basic MVC project that utilizes BootStrap4 and dataTables.Net. When the page loads, an Ajax call is made to fetch data for a table. However, despite following the documentation, I'm unable to get the buttons to display on the page. Everything ...

Retrieving the values of a particular row in a table multiple times using angular JS and filters

I am currently making a call to an API that will provide me with a JSON object. From this JSON object, I am extracting values based on certain conditions and displaying them in a table using AngularJS. The challenge I am facing now is retrieving the data f ...

Tips for incorporating material-ui icons into the column component of a data-grid component

I am currently working with the material-ui data-grid and I would like to display Edit icons from material-ui next to each row. Unfortunately, the data-grid does not provide any props specifically for this purpose. Below is the code snippet: import React ...

json data hidden from sight in jQuery

Snippet of HTML Code: <select name="ser" id="ser" class="form-control" onchange="getPrice(this.value);"> <option value="">--Select--</option> <option value="Value11">Value1</option> <option value="Value2">Value2</op ...

Error encountered with NG6 Angular sass files

Lately, I've been experimenting with NG6 Angular and it's growing on me. However, I hit a roadblock when attempting to switch from its default stylus to SASS, which is my preferred style in other projects. I have all the necessary dependencies in ...

What could be causing the malfunction in this JavaScript and WebRTC code?

<!DOCTYPE html> <html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <title>Vid Chat App</title> </head> <body> <video controls autoplay> </video> <script src="https: ...

A step-by-step guide to moving Vue .prototype to its own file

I have a couple of functions that I need to add to Vue's .prototype. However, I don't want to clutter up the main.js file. I attempted to move the prototypes like this: //main.js import "./vue-extensions/prototypes"; ...

Establish the editor's starting state

Currently, I am utilizing lexical and aiming to establish initial text for the editor. At the moment, my approach involves hardcoding the initial text, but it seems I cannot simply pass a String as anticipated. Instead, the format required is JSON. Hence ...

Utilizing jQuery to Detect TAB Key Press in Textbox

I need to detect when the TAB key is pressed, prevent the default action from occurring, and then execute my custom JavaScript function. ...

JavaScript event listener for SVG path element click is not functioning correctly as anticipated

How to determine if an element or its children have been clicked? I am trying to identify when a parent element or any of its child SVG icons with the attribute name set to "setGameState" have been clicked. The issue I am facing is that sometimes the even ...

What could be causing the issue with React Router not functioning properly in Material UI?

I'm currently working on creating a tab and adding routing inside the first tab. However, I am facing an issue where the desired page does not display after clicking on the link. Strangely, upon refreshing the page, the corresponding page appears as e ...

What is the process for integrating Firebase into $asyncValidators?

I am looking to implement a feature in my Firebase app that ensures usernames are unique. I want the user to be promptly informed if a username is already taken or not. I have been exploring AngularJS's ngModel as it offers an asyncValidator in its co ...

Consolidate all data connected to the specified key from a JSON dataset

Looking at the json string presented below [{"_id":"9/17/2015","amt1":0,"amt2":13276.5},{"_id":"9/18/2015","amt1":8075,"amt2":6445.5}] The expected outcome is: [{"_id": ["9/17/2015", "9/18/2015"], "amt1": [0, 8075], "amt2": [13276.5, 6445.5]}] Is there ...

Executing npm scripts in Node.js

Trying to move away from using the likes of Grunt or Gulp in my projects, I've been exploring npm-scripts as a potential replacement. While npm-scripts makes use of `package.json`, I've found that more advanced build processes require command lin ...

Automatically increase the dates in two cells once they have passed

Summary: Although I'm not a programmer, I've managed to incorporate some complex coding into a Google Sheets document for tracking my team's projects. This includes multiple-variable dropdown menus and integration with Google Calendar to mo ...