Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent ngRepeat flicker with promise in AngularJS

I have a collection of objects, say Products, which I can interact with using $resource. On an index page, I'd like to either display the collection, or, in the case the collection is empty, display a helpful message. i.e.

In Controller

$scope.products = Products.query();

In Template

<div ng-repeat="product in products">
  ...
</div>

<div class="alert" ng-hide="products.length">
  <p>Oops, no products!</p>
</div>

This works fine, provided the user isn't staring at the spot where the ng-repeat will occur. If they are, or if there is a delay in the response from the server, they may notice a slight flicker, before the promise is resolved.

Given that, "invoking a $resource object method immediately returns an empty reference" (see here), such a flicker will always in this example. Instead, I find myself writing:

<div class="alert" ng-hide="!products.$resolved || products.length">
  <p>Oops, no products!</p>
</div>

Which takes care of the flicker. However, I'm not too keen on letting my view know exactly how the products are obtained. Especially if I change this later on. Is there anything cleaner I could do? I'm aware that a fallback for ng-repeat is in the works (see here), however, just wondering if there's a cleaner solution in the meantime.

like image 607
Patrick McLaren Avatar asked Mar 19 '23 03:03

Patrick McLaren


1 Answers

You could use the success method to set the object:

Products.query(function(data) {
    $scope.products = data;
});

Or use the promise:

Products.query().$promise.then(function(data) {
   $scope.products = data;
});

This way, the object doesn't become empty until you get a response.

like image 185
dave Avatar answered Apr 01 '23 13:04

dave