1

Situation: We use AngularJS Material. It takes some time (up to several seconds) to render the data into the design.

Question: For this wait duration, we would like to show a loading element to signal the user that the website is working. However, what is the event for that? How can this be accomplished?


What we tried so far (and did not work):

$scope.loading = true; //shows a loading throbber

$http.get('/data.json').success(function(afts){
    $scope.afts = afts;
    $scope.loading = false; //hides the loading throbber
});

However, this only shows the loading throbber for a fraction of a second because the time consuming part is not loading the data, but rendering it (what happens when assigning the data/afts to the $scope).

Is there another event which is triggered when the rendering of this new data is complete?


How it should look like while rendering the data:

enter image description here


And this is how it looks now:

enter image description here


Steps to reproduce:

  1. Visit [example no longer available. AngularJS was too slow, we replaced it with a faster technology]
  2. Enter a location where it says "Mein Start-Ort (Adresse) in the top left corner
  3. Choose a location from the dropdown or hit "ENTER"
  4. Then you will experience a gap of a view seconds until you see the items listed below. During that time, a loading throbber should appear, but does not yet.
Simon Ferndriger
  • 4,455
  • 6
  • 28
  • 53
  • Bonus question: would it be possible to speed up to render process? How? – Simon Ferndriger Jan 30 '17 at 16:19
  • How much do I get for the question and how much for the bonus question? You can call to callback function when the last item in the `ng-repeat` will render. See [this](http://stackoverflow.com/q/15207788/863110) question. – Mosh Feu Jan 30 '17 at 16:25
  • @MoshFeu If you show my a way to progressively load/render the data (i.e. show the user some items fast, and the rest later), I give you 50 points – Simon Ferndriger Feb 02 '17 at 10:13
  • Just kidding.. It was a bit strange to phrase the question that way, it sounds like a test. I should add Smiley :). Anyway, you can do this but splitting the array for let's say 5 items, waiting couple of seconds and then push the rest to the scope. – Mosh Feu Feb 02 '17 at 11:04
  • Also you can search for `lazy loading list angularjs`. I found [this](http://stackoverflow.com/a/32087323/863110) answer. – Mosh Feu Feb 02 '17 at 11:06
  • @MoshFeu :) Thanks! – Simon Ferndriger Feb 02 '17 at 11:57
  • My pleasure :) If you get trouble with this, let me know. Good luck.. – Mosh Feu Feb 02 '17 at 15:47
  • @MoshFeu It worked, thanks! Can you post this as answer, I want to make it official ;) PS: I would like to really reward your work, if you could help make this thing fast, i.e. I want to lazy load the constructed graphs, they take up to 21 seconds to load on medium cpu power! – Simon Ferndriger Feb 02 '17 at 16:11
  • Just did, thanks, really appreciate (sadly, not all of the users knows to appreciate). For the second request, please contact me via linkedin (in my profile page), I will try to help you (I will be available after the weekend) – Mosh Feu Feb 02 '17 at 17:26
  • 1
    @MoshFeu You are very welcome :) Thank you for your offer, we will first try using PHP for rendering it hardcoded and then use Angular only for the sorting mechanism. I'll get back to you if it doesn't work out ;) – Simon Ferndriger Feb 03 '17 at 11:52

1 Answers1

1

You can split the source array - at the first take some (let's say 5) items. Wait for couple of seconds then push the others.

Something like this (It's dummy example, Just POC):

angular.module('app', []).
controller('ctrl', function($scope, $timeout) {
  var sourceArr = 'abcdefghijklmnopqrstuvwxyz'.split('');
  $scope.items = sourceArr.slice(0, 5);
  $timeout(function() {
    $scope.items.push(...sourceArr.slice(5, sourceArr.length));
  }, 2000);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
  <ul>
    <li ng-repeat="item in items">{{item}}</li>
  </ul>
</div>

This is a naive solution. You can use a more smart code just like in this answer.

Community
  • 1
  • 1
Mosh Feu
  • 28,354
  • 16
  • 88
  • 135