sairam
sairam

Reputation: 131

AngularJS: show loader image until data is loaded

screen image1

screen image2

displaying results using angular js + php, how to show loader image until data is loaded, here my code is written below,

How do I have AngularJS show a loading image until the data has finished loading?

app.js file

var app = angular.module('myApp3', ['ui.bootstrap']);

app.filter('startFrom', function() {

    return function(input, start) {
        if(input) {
            start = +start; //parse to int
            return input.slice(start);
        }
        return [];
    }
});
app.controller('customersCrtl', function ($scope, $http, $timeout) {
    $http.get('http://www.testurl.com/index.php/site/getprofileLocations').success(function(data){

        $scope.list = data;
        $scope.currentPage = 1; //current page
        $scope.entryLimit = 20; //max no of items to display in a page
        $scope.filteredItems = $scope.list.length; //Initially for no filter  
        $scope.totalItems = $scope.list.length;
    });
    $scope.setPage = function(pageNo) {
        $scope.currentPage = pageNo;
    };
    $scope.filter = function() {
        $timeout(function() { 
            $scope.filteredItems = $scope.filtered.length;
        }, 10);
    };
    $scope.sort_by = function(predicate) {
        $scope.predicate = predicate;
        $scope.reverse = !$scope.reverse;
    };
});

and php code is here

<html ng-app="myApp3" ng-app lang="en">


<div ng-controller="customersCrtl">
<div class="content" >

    <div class="row">
        <div class="col-md-2">PageSize:
            <select ng-model="entryLimit" class="form-control">
                <option>5</option>
                <option>10</option>
                <option>20</option>
                <option>50</option>
                <option>100</option>
            </select>
        </div>
        <div class="col-md-3">Filter:
            <input type="text" ng-model="search" ng-change="filter()" placeholder="Filter" class="form-control" />
        </div>
        <div class="col-md-4">
            <h5>Filtered {{ filtered.length }} Of {{ totalItems}} Total Locations</h5>
        </div>
    </div>
    <br/>
    <div class="row">
        <div class="col-md-12" ng-show="filteredItems > 0">
            <table class="table table-striped table-bordered">
            <thead>
            <th>Id&nbsp;<a ng-click="sort_by('id');"><i class="glyphicon glyphicon-sort"></i></a></th>
            <th>Place Name&nbsp;<a ng-click="sort_by('name');"><i class="glyphicon glyphicon-sort"></i></a></th>
            <th>Category ID&nbsp;<a ng-click="sort_by('category_name');"><i class="glyphicon glyphicon-sort"></i></a></th>


            </thead>
            <tbody>
                <tr ng-repeat="data in filtered = (list | filter:search | orderBy : predicate :reverse) | startFrom:(currentPage-1)*entryLimit | limitTo:entryLimit">
                   <td>{{data.id}}</td>
                    <td>{{data.name}}</td>
                    <td>{{data.category_name}}</td>



                </tr>
            </tbody>
            </table>
        </div>
        <div class="col-md-12" ng-show="filteredItems == 0">
            <div class="col-md-12">
                <h4>No Locations found</h4>
            </div>
        </div>
        <div class="col-md-12" ng-show="filteredItems > 0">    
            <div pagination="" page="currentPage" on-select-page="setPage(page)" boundary-links="true" total-items="filteredItems" items-per-page="entryLimit" class="pagination-small" previous-text="&laquo;" next-text="&raquo;"></div>


        </div>
    </div>
</div>
</div>

<script src="<?php echo Yii::app()->baseUrl; ?>/angular/js/angular.min.js"></script>
<script src="<?php echo Yii::app()->baseUrl; ?>/angular/js/ui-bootstrap-tpls-0.10.0.min.js"></script>
<script src="<?php echo Yii::app()->baseUrl; ?>/angular/app/app.js"></script>

</html>

Upvotes: 5

Views: 31057

Answers (6)

Leonardo Lima
Leonardo Lima

Reputation: 140

There is a better way that prevents showing two icons for example:

(BAD WAY)

When angular is manipulating the DOM, it can show the search icon before hiding the loading icon. Thats why its bad to have two elements.

<i class="fa fa-search" ng-hide="loadingData" ></i>
<i class="fa fa-circle-o-notch fa-spin" ng-show="loadingData"></i>

(GOOD WAY)

This way prevents showing the loading and the search icon when angular is hiding and showing elements.

<i class="fa" ng-class="loadingData ?  'fa-circle-o-notch fa-spin' : 'fa-search' " ></i>

And the script would be something like this.

$scope.clickEventThatDoSomething = function () {
    $scope.loadingData = true;
    http.get('http://YourAPIUrl').then(function (data) {
        $scope.loadingData = false;
        $scope.data = data.data;
    }).catch(function (err) {
        $scope.loadingData = false;
    })
}

Upvotes: 0

Rajashekhar Reddy
Rajashekhar Reddy

Reputation: 107

Whenever we use an HTTP call in AngularJS, we want to show the loading image by default. So here, we are going to achieve this by using a custom directive.

JS CODE

var app = angular.module('appMyCustomModule',[]);
app.directive('dirCustomLoader', ['$http', function ($http) {
    return {
        restrict: 'E',
        template: '<div class="loading-icon"></div>',
        link: function (scope, element, attrs) {
            scope.isLoading = function () {
                return $http.pendingRequests.length > 0;
            };
            scope.$watch(scope.isLoading, function (value) {
                if (value) 
                    element.removeClass('ng-hide');
                else 
                    element.addClass('ng-hide');
            });
        }
    };
}]);

CSS:

.loading-icon {
    background: url(static image url) no-repeat scroll center #fff;
    display: inline-block;
    font-size: 0;
    height: 100%;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 9999999999999999999 !important;
    opacity: .5;
}

HTML CODE:

<dir-custom-loader class="ng-hide"></dir-custom-loader>

Upvotes: 0

Rahul
Rahul

Reputation: 334

You can do one thing:

  • Keep hidden your html content by default
  • Show it when you get the response

like:

<div class="content" ng-show="!showLoader">
   .....
</div>

So using this only loader will show till you get your data from server.

Upvotes: 0

dreamweiver
dreamweiver

Reputation: 6002

You need to show the loader image before the ajax call and remove it after it completes in both success and error handler.

you will find plenty of loader images online, which you can use it for your application.

JS CODE

 //show the loader image in center of screen & prevent any user interactions
 $scope.imLoading = true;
 $http.get('http://www.testurl.com/index.php/site/getprofileLocations').then(
   function(data){
       //hide the loader image & process successful data. 
       $scope.imLoading = false;    
   }, function (errorData) {
       //hide the loader image & show error message to user
       $scope.imLoading = false;
 });

CSS:

.im_loading{
 display:none;
 position:fixed;
 top:50%;
 left:50%;
 margin:-35px 0px 0px -35px;
 background:#fff url(../images/loader.gif) no-repeat center center;
 width:70px;
 height:70px;
 z-index:9999;
 -moz-border-radius:10px;
 -webkit-border-radius:10px;
 border-radius:10px;
 -moz-box-shadow:1px 1px 3px #000;
 -webkit-box-shadow:1px 1px 3px #000;
 box-shadow:1px 1px 3px #000;
 opacity:0.7;
 filter:progid:DXImageTransform.Microsoft.Alpha(opacity=70);
}

HTML CODE:

<div class="im_loading" ng-show:"imLoading"></div>

Note: Your code is proccessing only successful ajax call & not erroneous call which is not good as your code becomes unresponsive when error is returned, so you need to handle error case as well.

Upvotes: 0

Venugopal
Venugopal

Reputation: 1896

display loader onload and hide it once data loaded.

$scope.showLoader = true;
$http.get('http://www.testurl.com/index.php/site/getprofileLocations').success(function(data){
    $scope.showLoader = false;
    // rest of your code
});

EDIT: html code from Saeed's answer

<div ng-show="showLoader"><!-- so this div containing img will be dislpayed only when the showLoader is equal to true-->
    <img src="source"> <!-- or any other spinner -->
</div>

Upvotes: 20

Saidbek Arislonov
Saidbek Arislonov

Reputation: 56

Addition to @Venugopal`s answer. To display that loading image in the html

<div ng-show="showLoader"><!-- so this div containing img will be dislpayed only when the showLoader is equal to true-->
  <img src="source"> <!-- or any other spinner -->
</div>

Upvotes: 1

Related Questions