Hide preloader in AngularJS once repeater has completed execution

Is there a way to hide a preloader div only after all data has finished loading in an ng-repeat loop?

Check out this interactive example on Plunker: http://plnkr.co/edit/ilgOZzIy2axSi5Iy85C7?p=preview

Here is the HTML code:

<div ng-controller="locationAccordionCtrl">
    <div ng-repeat="location in locations" on-finish-render="ngRepeatFinished">

      {{location.siteName}}

      <ul>
          <li ng-repeat="listOfLocations in location.locationsList track by $index">
              {{listOfLocations}}
          </li>
      </ul>

    </div>
</div>

This is the Controller code:

App.controller('locationAccordionCtrl', function ($scope) {

  $scope.locations = [
    {
      "siteName":"First Location",
      "locationsList":['First Location 1', 'First Location 2', 'First Location 3']
    },
    {
      "siteName":"Second Location",
      "locationsList":['Second Location 1', 'Second Location 2', 'Second Location 3']
    },
    {
      "siteName":"Third Location",
      "locationsList":['Third Location 1', 'Third Location 2', 'Third Location 3']
    }
  ];

// Custom directive to hide preloader after repeater finishes loading data
App.directive('onFinishRender', function ($timeout) {
    return {
        restrict: 'A',
        link: function (scope, element, attr) {
            if (scope.$last === true) {
                $timeout(function () {
                    scope.$emit('ngRepeatFinished');
                });
            }
        }
    }
});

// Hide the preloader
$scope.$on('ngRepeatFinished', function(ngRepeatFinishedEvent) {
    $scope.hidePreLoader = true;
});

});

Answer №1

Have you considered using $broadcast in place of $emit? Broadcasting your event downwards can be more effective than emitting it upwards in the scope hierarchy.

To address the issue, you can ensure that the $rootScope broadcasts the event downwards:

$rootScope.$broadcast('ngRepeatFinished');

$rootScope.$on('ngRepeatFinished', function(ngRepeatFinishedEvent) {
    $scope.hidePreLoader = true;
});

Answer №2

To simplify the ng-repeat block, you can incorporate a method call within it. This will help improve efficiency and readability of your code.

<div ng-repeat="location in locations" ng-init="clearLoader(($index + 1) == locations.length)">
    ...
</div>

Subsequently, in your controller section:

$scope.clearLoader = function (isLastItem) {
    if (isLastItem)
        $scope.hidePreLoader = true;
}

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

Utilizing Node.js to insert a new image path into MongoDB

I have successfully stored image paths in MongoDB in array format. Now, I need to figure out how to add another image path to the existing array using the document ID. How can I achieve this in MongoDB? Currently, I am uploading images using an HTML file. ...

Click event from Angular Material menu is triggered twice on mobile devices

After implementing a basic angular material side menu from the demo, I noticed that all click events are being fired twice on the entire page when viewed in mobile browsers. This issue can even be replicated in the Chrome emulator. (To reproduce, enable th ...

Enhancing the tooltip inner content in Bootstrap with a description:

Can you help me troubleshoot the code below? I am trying to add a description to numbers in my tooltip, but it doesn't seem to be working. Here is the HTML: <input id="contract-length" class="slider slider-step-2 slider-contract-length" ...

Clear cache folders in the cordova and ionic file systems to free up space

In a mobile app, I need to delete the cached images that are downloaded by a specific user after they log out. For example, if user1 logs in and downloads some images, and then user2 logs in and downloads other images, user2 should not see the images dow ...

How can I target only one mapped item when using onClick in React/NextJS?

Apologies if this question is repetitive, but I couldn't find a better way to phrase my issue. The code in question is as follows: const [isFlipped, setFlipped] = useState(false); const flip = () => { if (!isFlipped) { setFlipped(tr ...

I am facing an issue where this loop is terminating after finding just one match. How can I modify it to return

I am currently working with an array that compares two arrays and identifies matches. The issue is that it only identifies one match before completing the process. I would like it to identify all matches instead. Can anyone explain why this is happening? ...

Tips for implementing JWT in a Node.js-based proxy server:

I am a Node.js beginner with a newbie question. I'm not sure if this is the right place to ask, but I need ideas from this community. Here's what I'm trying to do: Server Configurations: Node.js - 4.0.0 Hapi.js - 10.0.0 Redis Scenario: ...

Troubleshoot: Node Express experiencing issues reconnecting to ajax

Here is the initial question that needs to be addressed. I am currently developing an API that links a front-end application (built using node, express, and Ajax) with a Python swagger API. The issue I am facing is that although I can successfully send da ...

Setting a default value in Vue props if it doesn't pass validation: A guide

Is it possible to assign a default value to a prop using a validator? For instance, if the current prop does not pass the validator and is less than 3, I would like to automatically set the value to 1. Here's an example: currentStep: { type ...

Ways to Deduct 10 Days from a Date using JavaScript

After receiving some helpful suggestions, I managed to solve my date issue by using moment.js. Here is the snippet of code where I implemented moment.js: var preorderdate = moment(date).subtract('days',10).format('MMMM D, YYYY'); var r ...

A method for increasing a counter using only an instance of a class or function without accessing its methods or properties in Javascript

Looking at the task ahead, let increment = new Increment(); I have been tasked with creating a Javascript class or function called Increment in order to achieve the following: console.log(`${increment}`) // should output 1 console.log(`${increment}`); ...

Node JS Promise does not provide a value as a return

Struggling with getting a value back from the code snippet below, even though it console logs out without any issues. Any suggestions on how to assign a value to X? var dbSize = dbo.collection('Items').count() var x = 0 x = dbS ...

Error encountered while parsing a file: JSON parsing failed due to an unexpected token 'g' at position

https.get('example.com/phpfilethatechoesandimtryingtograbtheecho.php', (res) => { console.log('statusCode:', res.statusCode); onsole.log('headers:', res.headers); res.on('data', (d) => { return ...

Set the HTML content as a string in the Html variable, similar to innerHTML but without using JavaScript directly from an external

When working in an embedded ruby (html.erb) file, I encounter a situation where I have a string of HTML such as variable_string = "<p>Some <strong>Content</strong></p>". In JavaScript, we can easily update the DOM with Element.inn ...

I'm experiencing difficulties with JS on my website. Details are provided below – any suggestions on how to resolve this issue

Can someone help me with a web project issue I'm facing? Everything was going smoothly until I tried to add some JS for dynamic functionality. However, when I attempt to access my elements by tag name, ID, or class, they always return null or undefine ...

Is there a way to verify the visibility of an element in Protractor?

Currently, I am utilizing Protractor for conducting my comprehensive end-to-end tests. A few elements have been configured with ng-show attributes. Would someone kindly advise me on how to validate whether these elements are visible or not using Protracto ...

How can Angular's as-syntax be used to access the selected object?

When using syntax like ng-options="p.id as p.name for p in options" to select options, I encounter an issue. I require access to the variable p as well. This is necessary for displaying additional labels near inputs or buttons, or even making changes to in ...

Error encountered while using Google Translate with XMLHttpRequest (Missing 'Access-Control-Allow-Origin' header)

Trying to access a page that utilizes Google Translate is resulting in the following error: XMLHttpRequest cannot load http://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit. No 'Access-Control-Allow-Origin' heade ...

Exploring the powerful capabilities of utilizing state variables within styled components

I'm attempting to create a button that changes its state based on the value of a property within an object. Below is the styled component const Btn = styled.button` border-radius: ${props => props.theme.radius}; padding:5px 10px; backgroun ...

Formatting Date and Time in the Gridview of my Asp.net Application

I have been using this format to display the date and time in a grid. The issue I am facing is that I cannot retrieve the exact HH:MM from the database. Even though the database shows 11:11, my grid is displaying 11:03 instead. Here is the value stored in ...