development icon

Present data from an API with a variety of different views using Angular

Cara Lemieux, Senior Communication Strategist
#Angular | Posted

Recently I’ve been working on a few different projects that make use of AngularJS. The projects are similar: mobile-focused web applications which read and present data from an API with a variety of different views or ‘pages.’

There are two popular ways of handling the routing of your application to different views: Angular comes with a built-in module called ngRoute, and the other popular module is called ui-router from the angular-ui project.

It is easy when you’re first getting started with Angular to set up some basic routes and then in your controllers communicate with your API to fetch some data and display it to the user. What can happen, though, is that your API might be a bit slow to respond and your visitor will get presented with a mostly empty screen that suddenly flashes full of content, or perhaps even be shown your raw template code until the data arrives.

Not a great experience!

Luckily, both ngRoute and ui-router have the concept of dependency loaders called “resolve.” By setting up resolves and communicating with your API in them, you can hold the user from seeing the new view until all of the data has been loaded and is ready. No more flash of empty screens or raw template code while you wait for your API to return is a much better experience!

But (there’s always a but) by default your application isn’t going to do anything to indicate that it’s waiting on the API, which can mean that a user taps or clicks on a link and then … nothing … and then still nothing … did I really click that? … maybe I should click it aga–oh! something happened!

Neither ngRoute or ui-router resolves give the user any sort of indication that something is happening in the background in-and-of-themselves, but luckily it isn’t super complicated to add loading indicators into your application. Here’s how:

For these examples we’re going to use some sweet CSS-based loading indicators called Spinkit, which are available as an Angular module called angular-spinkit. Be sure to follow the instructions to include angular-spinkit into your application and don’t forget to declare the dependency in your Angular application.

For both examples we will create a directive which will show a loading message and animation and we will register listeners to the routing system to watch for route change events to toggle the display of the loading indicator.

First, let’s look at integrating this with ngRoute:

screenshot of Code snippet of integration into ngroute

A pretty simple directive called routeLoadingIndicator. It makes itself available as an element<route-loading-indicator></route-loading-indicator>and it displays a very simple loading message:

loading image

Thelinkfunction of the directive is the important part: we register two event listeners for the events$routeChangeStartand$routeChangeSuccesswhich toggle a scope variableisRouteLoadingwhich is used in the loading screen template in anng-showdirective.

Pretty simple and it has the effect of showing a loading message while the app is loading dependencies for the next route. You can use theisRouteLoadingscope variable in your route templates to do the opposite of the loading screen:ng-show='!isRouteLoading'to hide their content when you display your loading message.

The ui-router module works almost the same way. Instead of declaring ‘routes’ you declare ‘states’ so we’ll update some of our language for ui-router:

app.directive('stateLoadingIndicator', function($rootScope) {

  return {

    restrict: 'E',

    template: "<div ng-show='isStateLoading' class='loading-indicator'>" +

    "<div class='loading-indicator-body'>" +

    "<h3 class='loading-title'>Loading...</h3>" +

    "<div class='spinner'><chasing-dots-spinner></chasing-dots-spinner></div>" +

    "</div>" +

    "</div>",

    replace: true,

    link: function(scope, elem, attrs) {

      scope.isStateLoading = false;

      $rootScope.$on('$stateChangeStart', function() {

        scope.isStateLoading = true;

      });

      $rootScope.$on('$stateChangeSuccess', function() {

        scope.isStateLoading = false;

      });

    }

  };

});

The events we listen to in ui-router are$stateChangeStartand$stateChangeSuccesswhich function the same way as ngRoute’s$routeChangeStartand$routeChangeSuccessevents.

loading image

So there you have it, two easy to implement directives that use either ngRoute or ui-router and allow you to add simple loading messages to give your users some indication that something is happening as you transition them through different views of your application.

If you’d like to show loading indicators within your view – perhaps user interaction queries an API and updates something in that view, like a data table, I’d recommend checking out the angular module angular-busy.

Find more P2 thoughts on AngularJS on the blog!

Cara Lemieux

Senior Communication Strategist