How to Load Spinner in AngularJs

Rana Hasnain Khan Feb 02, 2024
How to Load Spinner in AngularJs

We will introduce how to add a loading spinner while the request is loading and stop the loader when the data is loaded in AngularJs.

Loading Spinner in AngularJs

Loaders are a part of web applications to make them user-friendly and improve the user interface. Loaders are displayed when the data fetching takes longer, and instead of displaying a blank page, we choose to display a loader.

Loader animations keep users engaged while the data is loading. We will go through an example in which we will display 6 images and use a loader animation to delay the display of images.

Let’s create a new AngularJs application to go through an example of directives.

First of all, we will add the AngularJs library using script tags.

# AngularJs
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.min.js"></script>

Now, we will define AngularJs application using ng-app.

# AngularJs
<body ng-app="">
   ...
</body>

We will create a heading using h2. After that, we will create a div with class loadImages and the ng-if statement that will use variable images; if it is set to true, it will display images. If it is set to false, images will be hidden.

Inside our loadImages div, we will create one more div with classes img-box that will have 2 more div inside it with classes loader-box and img with ng-if statements. Only the loader-box div will be displayed if the variable loader is true.

If the loader is false, it hides the loader box and displays images. Inside our loader-box, we will create an SVG loader animation, and inside our img div, we will display our image.

We will display 6 images in our template by copying the structure we just made. So our code will look like below.

# AngularJs
<div class="container" ng-app="myApp" ng-controller="Controller">

  <h2>Images Of Cat</h2>
<div ng-If="images == true" class="loadImages">
  <div class="img-box">
    <div ng-If="loader == true" class="loader-box">
      <svg
        xmlns="https://www.w3.org/2000/svg"
        xmlns:xlink="https://www.w3.org/1999/xlink"
        style="margin: auto; background: rgb(255, 255, 255); display: block; shape-rendering: auto;"
        width="200px"
        height="200px"
        viewBox="0 0 100 100"
        preserveAspectRatio="xMidYMid"
      >
        <circle
          cx="50"
          cy="50"
          r="0"
          fill="none"
          stroke="#e90c59"
          stroke-width="2"
        >
          <animate
            attributeName="r"
            repeatCount="indefinite"
            dur="1s"
            values="0;40"
            keyTimes="0;1"
            keySplines="0 0.2 0.8 1"
            calcMode="spline"
            begin="0s"
          ></animate>
          <animate
            attributeName="opacity"
            repeatCount="indefinite"
            dur="1s"
            values="1;0"
            keyTimes="0;1"
            keySplines="0.2 0 0.8 1"
            calcMode="spline"
            begin="0s"
          ></animate>
        </circle>
        <circle
          cx="50"
          cy="50"
          r="0"
          fill="none"
          stroke="#46dff0"
          stroke-width="2"
        >
          <animate
            attributeName="r"
            repeatCount="indefinite"
            dur="1s"
            values="0;40"
            keyTimes="0;1"
            keySplines="0 0.2 0.8 1"
            calcMode="spline"
            begin="-0.5s"
          ></animate>
          <animate
            attributeName="opacity"
            repeatCount="indefinite"
            dur="1s"
            values="1;0"
            keyTimes="0;1"
            keySplines="0.2 0 0.8 1"
            calcMode="spline"
            begin="-0.5s"
          ></animate>
        </circle>
      </svg>
    </div>
    <div ng-If="loader == false" class="img">
      <img
        src="https://images.pexels.com/photos/3777622/pexels-photo-3777622.jpeg?auto=compress&cs=tinysrgb&w=175&fit=crop&h=275&dpr=1"
        alt=""
      />
    </div>
  </div>
  <div class="img-box">
    <div ng-If="loader == true" class="loader-box">
      <svg
        xmlns="https://www.w3.org/2000/svg"
        xmlns:xlink="https://www.w3.org/1999/xlink"
        style="margin: auto; background: rgb(255, 255, 255); display: block; shape-rendering: auto;"
        width="200px"
        height="200px"
        viewBox="0 0 100 100"
        preserveAspectRatio="xMidYMid"
      >
        <circle
          cx="50"
          cy="50"
          r="0"
          fill="none"
          stroke="#e90c59"
          stroke-width="2"
        >
          <animate
            attributeName="r"
            repeatCount="indefinite"
            dur="1s"
            values="0;40"
            keyTimes="0;1"
            keySplines="0 0.2 0.8 1"
            calcMode="spline"
            begin="0s"
          ></animate>
          <animate
            attributeName="opacity"
            repeatCount="indefinite"
            dur="1s"
            values="1;0"
            keyTimes="0;1"
            keySplines="0.2 0 0.8 1"
            calcMode="spline"
            begin="0s"
          ></animate>
        </circle>
        <circle
          cx="50"
          cy="50"
          r="0"
          fill="none"
          stroke="#46dff0"
          stroke-width="2"
        >
          <animate
            attributeName="r"
            repeatCount="indefinite"
            dur="1s"
            values="0;40"
            keyTimes="0;1"
            keySplines="0 0.2 0.8 1"
            calcMode="spline"
            begin="-0.5s"
          ></animate>
          <animate
            attributeName="opacity"
            repeatCount="indefinite"
            dur="1s"
            values="1;0"
            keyTimes="0;1"
            keySplines="0.2 0 0.8 1"
            calcMode="spline"
            begin="-0.5s"
          ></animate>
        </circle>
      </svg>
    </div>
    <div ng-If="loader == false" class="img">
      <img
        src="https://images.pexels.com/photos/156321/pexels-photo-156321.jpeg?auto=compress&cs=tinysrgb&w=175&fit=crop&h=275&dpr=1"
        alt=""
      />
    </div>
  </div>
  <div class="img-box">
    <div ng-If="loader == true" class="loader-box">
      <svg
        xmlns="https://www.w3.org/2000/svg"
        xmlns:xlink="https://www.w3.org/1999/xlink"
        style="margin: auto; background: rgb(255, 255, 255); display: block; shape-rendering: auto;"
        width="200px"
        height="200px"
        viewBox="0 0 100 100"
        preserveAspectRatio="xMidYMid"
      >
        <circle
          cx="50"
          cy="50"
          r="0"
          fill="none"
          stroke="#e90c59"
          stroke-width="2"
        >
          <animate
            attributeName="r"
            repeatCount="indefinite"
            dur="1s"
            values="0;40"
            keyTimes="0;1"
            keySplines="0 0.2 0.8 1"
            calcMode="spline"
            begin="0s"
          ></animate>
          <animate
            attributeName="opacity"
            repeatCount="indefinite"
            dur="1s"
            values="1;0"
            keyTimes="0;1"
            keySplines="0.2 0 0.8 1"
            calcMode="spline"
            begin="0s"
          ></animate>
        </circle>
        <circle
          cx="50"
          cy="50"
          r="0"
          fill="none"
          stroke="#46dff0"
          stroke-width="2"
        >
          <animate
            attributeName="r"
            repeatCount="indefinite"
            dur="1s"
            values="0;40"
            keyTimes="0;1"
            keySplines="0 0.2 0.8 1"
            calcMode="spline"
            begin="-0.5s"
          ></animate>
          <animate
            attributeName="opacity"
            repeatCount="indefinite"
            dur="1s"
            values="1;0"
            keyTimes="0;1"
            keySplines="0.2 0 0.8 1"
            calcMode="spline"
            begin="-0.5s"
          ></animate>
        </circle>
      </svg>
    </div>
    <div ng-If="loader == false" class="img">
      <img
        src="https://images.pexels.com/photos/3054570/pexels-photo-3054570.jpeg?auto=compress&cs=tinysrgb&w=175&fit=crop&h=275&dpr=1"
        alt=""
      />
    </div>
  </div>
  <div class="img-box">
    <div ng-If="loader == true" class="loader-box">
      <svg
        xmlns="https://www.w3.org/2000/svg"
        xmlns:xlink="https://www.w3.org/1999/xlink"
        style="margin: auto; background: rgb(255, 255, 255); display: block; shape-rendering: auto;"
        width="200px"
        height="200px"
        viewBox="0 0 100 100"
        preserveAspectRatio="xMidYMid"
      >
        <circle
          cx="50"
          cy="50"
          r="0"
          fill="none"
          stroke="#e90c59"
          stroke-width="2"
        >
          <animate
            attributeName="r"
            repeatCount="indefinite"
            dur="1s"
            values="0;40"
            keyTimes="0;1"
            keySplines="0 0.2 0.8 1"
            calcMode="spline"
            begin="0s"
          ></animate>
          <animate
            attributeName="opacity"
            repeatCount="indefinite"
            dur="1s"
            values="1;0"
            keyTimes="0;1"
            keySplines="0.2 0 0.8 1"
            calcMode="spline"
            begin="0s"
          ></animate>
        </circle>
        <circle
          cx="50"
          cy="50"
          r="0"
          fill="none"
          stroke="#46dff0"
          stroke-width="2"
        >
          <animate
            attributeName="r"
            repeatCount="indefinite"
            dur="1s"
            values="0;40"
            keyTimes="0;1"
            keySplines="0 0.2 0.8 1"
            calcMode="spline"
            begin="-0.5s"
          ></animate>
          <animate
            attributeName="opacity"
            repeatCount="indefinite"
            dur="1s"
            values="1;0"
            keyTimes="0;1"
            keySplines="0.2 0 0.8 1"
            calcMode="spline"
            begin="-0.5s"
          ></animate>
        </circle>
      </svg>
    </div>
    <div ng-If="loader == false" class="img">
      <img
        src="https://images.pexels.com/photos/6869634/pexels-photo-6869634.jpeg?auto=compress&cs=tinysrgb&w=175&fit=crop&h=275&dpr=1"
        alt=""
      />
    </div>
  </div>
  <div class="img-box">
    <div ng-If="loader == true" class="loader-box">
      <svg
        xmlns="https://www.w3.org/2000/svg"
        xmlns:xlink="https://www.w3.org/1999/xlink"
        style="margin: auto; background: rgb(255, 255, 255); display: block; shape-rendering: auto;"
        width="200px"
        height="200px"
        viewBox="0 0 100 100"
        preserveAspectRatio="xMidYMid"
      >
        <circle
          cx="50"
          cy="50"
          r="0"
          fill="none"
          stroke="#e90c59"
          stroke-width="2"
        >
          <animate
            attributeName="r"
            repeatCount="indefinite"
            dur="1s"
            values="0;40"
            keyTimes="0;1"
            keySplines="0 0.2 0.8 1"
            calcMode="spline"
            begin="0s"
          ></animate>
          <animate
            attributeName="opacity"
            repeatCount="indefinite"
            dur="1s"
            values="1;0"
            keyTimes="0;1"
            keySplines="0.2 0 0.8 1"
            calcMode="spline"
            begin="0s"
          ></animate>
        </circle>
        <circle
          cx="50"
          cy="50"
          r="0"
          fill="none"
          stroke="#46dff0"
          stroke-width="2"
        >
          <animate
            attributeName="r"
            repeatCount="indefinite"
            dur="1s"
            values="0;40"
            keyTimes="0;1"
            keySplines="0 0.2 0.8 1"
            calcMode="spline"
            begin="-0.5s"
          ></animate>
          <animate
            attributeName="opacity"
            repeatCount="indefinite"
            dur="1s"
            values="1;0"
            keyTimes="0;1"
            keySplines="0.2 0 0.8 1"
            calcMode="spline"
            begin="-0.5s"
          ></animate>
        </circle>
      </svg>
    </div>
    <div ng-If="loader == false" class="img">
      <img
        src="https://images.pexels.com/photos/7149465/pexels-photo-7149465.jpeg?auto=compress&cs=tinysrgb&w=175&fit=crop&h=275&dpr=1"
        alt=""
      />
    </div>
  </div>
  <div class="img-box">
    <div ng-If="loader == true" class="loader-box">
      <svg
        xmlns="https://www.w3.org/2000/svg"
        xmlns:xlink="https://www.w3.org/1999/xlink"
        style="margin: auto; background: rgb(255, 255, 255); display: block; shape-rendering: auto;"
        width="200px"
        height="200px"
        viewBox="0 0 100 100"
        preserveAspectRatio="xMidYMid"
      >
        <circle
          cx="50"
          cy="50"
          r="0"
          fill="none"
          stroke="#e90c59"
          stroke-width="2"
        >
          <animate
            attributeName="r"
            repeatCount="indefinite"
            dur="1s"
            values="0;40"
            keyTimes="0;1"
            keySplines="0 0.2 0.8 1"
            calcMode="spline"
            begin="0s"
          ></animate>
          <animate
            attributeName="opacity"
            repeatCount="indefinite"
            dur="1s"
            values="1;0"
            keyTimes="0;1"
            keySplines="0.2 0 0.8 1"
            calcMode="spline"
            begin="0s"
          ></animate>
        </circle>
        <circle
          cx="50"
          cy="50"
          r="0"
          fill="none"
          stroke="#46dff0"
          stroke-width="2"
        >
          <animate
            attributeName="r"
            repeatCount="indefinite"
            dur="1s"
            values="0;40"
            keyTimes="0;1"
            keySplines="0 0.2 0.8 1"
            calcMode="spline"
            begin="-0.5s"
          ></animate>
          <animate
            attributeName="opacity"
            repeatCount="indefinite"
            dur="1s"
            values="1;0"
            keyTimes="0;1"
            keySplines="0.2 0 0.8 1"
            calcMode="spline"
            begin="-0.5s"
          ></animate>
        </circle>
      </svg>
    </div>
    <div ng-If="loader == false" class="img">
      <img
        src="https://images.pexels.com/photos/320014/pexels-photo-320014.jpeg?auto=compress&cs=tinysrgb&w=175&fit=crop&h=275&dpr=1"
        alt=""
      />
    </div>
  </div>
</div>

Once we have added images, we will add 2 buttons, one will hide the images, and one will load the images. We will use the ng-if statement to hide the buttons when not needed.

For example, the load images button will not show when the images are displayed. The hide images button will not show when the images are hidden.

These buttons will also have ng-Click events to loadImages() and hideImages() functions, respectively.

<button ng-If="images == false" ng-click="loadImages()">
  Click to view Images
</button>
<button ng-If="images == true" ng-click="hideImages()">
  Click to hide Images
</button>
</div>

Let’s write some CSS to organize our images and loader. So our code in CSS will be as below.

p {
  font-family: Lato;
}
h2 {
  text-align: center;
}
.img-box {
  width: 31%;
  float: left;
  border: 1px solid black;
  margin-right: 5px;
  margin-bottom: 5px;
}
.img-box svg {
  width: 100%;
}
.img-box .img {
  width: 100%;
  height: 200px;
  overflow: hidden;
}

We will define 2 variables inside our Js file named loader and images. We will use these in ng-if statements and set them false to hide on load images.

We will create the functions we used in the ng-click event on buttons. In loadImages, we will first set loader to true and create a setTimeout function to delay the loader animation for 2000ms.

After 2000ms, we will change the loader value to false and set the value of images to true to display the images with a loader animation.

Now, in hideImages() function we will only set the value of images to false. So code in our index.js file will look like below.

var myApp = angular.module('myApp', [])
.controller('Controller', function($scope){
  $scope.loader = false;
  $scope.images = false;
  $scope.loadImages = function(){
    $scope.loader = true;

  setTimeout(function () {
  $scope.$apply(function(){
      $scope.loader = false;
  });
  }, 2000);


    $scope.images = true;
  };
  $scope.hideImages = function(){
    $scope.images = false;
  };
});

You can check the code here.

Let’s check how our application works.

Output:

loading spinner in angularjs working animation

In this way, we can set a loading animation to any element in our AngularJs application.

But loader animations are mostly used in HTTP requests because they take time sometimes, and it is best to use loading animations to keep the user engaged instead of displaying a blank page until the data is loading.

Rana Hasnain Khan avatar Rana Hasnain Khan avatar

Rana is a computer science graduate passionate about helping people to build and diagnose scalable web application problems and problems developers face across the full-stack.

LinkedIn