Add a preloader to your website using AngularJS

Don’t you just hate it when you go to a website, and there is just a blank widget or section of the page! Initially one thinks the page is broke, until a few seconds later when the content actually loads up. This is not great in terms of UX, and there are ways to avoid this with AngularJS (and other libraries of course) to provide a much better experience to your visitors.

Preloaders

Preloaders are small and lightweight animations that indicate to the end user that something is churning away at the back-end of the application, and that nothing is broke. They give assurance to the end user and helps them relax, especially if your preloader is something catchy and nice, like those provided by our friends at codrops.

rubiks cube preloader
preloader

Let us see how we can implement a preloader in our AngularJS application.

Setting the scene

I have your average AngularJS application with a controller that makes a call to an API to retrieve some data and a view onto which we display the data.

In a real production application, you would most likely place the call to the API inside a service and then consume the service within the controller.

The application makes a call to an API I have created via ASP.Net Web API. Any request that comes in, is delayed by 3 seconds, then the data is served.

Implementation

Let us get down and dirty with code. If you think about it a little carefully you will realize that what we are wanting to achieve is quite simple.

Basically we want a preloader on our page that will show when the data is still loading, and hide when the data has finished loading.

So when the call to the API was a success and data is retrieved, we want to hide the preloader and show the retrieved data instead. Simple correct?

Here is our preloader markup:

And here is the CSS responsible for displaying the preloader image. I prefer using CSS to show images for preloaders. You can do this without CSS by simply using the HTML image tag.

Notice the use of the ngHide directive on the preloader markup. When the expression passed to that directive returns true, the directive hides the div it is applied to.

So we have set a boolean property of dataLoaded on our AbsentEmployees object on our controller’s scope. When this property is set to true (i.e. the data has loaded) the preloader is hidden.

Conversely on the markup responsible for displaying our retrieved data, we will make use of the ngShow directive. Which when passed an expression of true, will show the div it is applied to like so:

So the above code will only show when the call to the API was a success and the dataLoaded flag is set to true.

Finally, here is our angular controller code showing how we are handling the dataLoaded flag:

Notice how initially our dataLoaded flag is set to false, which makes sense as the call has not even taken place yet, so our preloader would show, thanks to the ngHide directive we used.

The Flicker Problem

When combating this problem, it is worth remembering that every script and line of html markup takes time to load, sure if you have a fast internet connection that time is so small that you hardly notice, but that is not always the case.

Sometimes even with a fast internet connection you would notice a flicker on the initial load of a page, this is bad and we would want to avoid this. There are a couple of things we can do to avoid this problem.

The first thing we will do is make use of the ngCloack directive. This directive will prevent the Angular html template from being briefly displayed by the browser in its raw (uncompiled) form while our application is loading.

You might think that is all that is required to get rid of the flicker problem, but you would be wrong.

Remember the ngClock directive will only ever do anything if the angularjs library has finished loading. If for whatever reason the angularjs library delays and is not loaded quick enough, we will still see a quick flicker of the page.

To overcome this we will make use of the ngInclude directive. Basically we will put all our markup within a partial view that will be pulled onto the page via angular.

As stated by the angularjs documentation, the ngInclude directive will fetches, compile and include an external HTML fragment.

The beauty of the above is that browsers have no idea what an ngInclude directive is, and so nothing will render onto the page until the angular library has finished loading.

Here is the markup contained within our UserAvailabilityWidgetBody partial view:

The result of the above code will be something similar to what is shown in the screenshot below:

preloader code result
preloader code result