Simulating Latency for AngularJS $http Calls with Response Interceptors

When writing an AngularJS application that communicates with back-end services via XHR calls, you need to cater for the latency that will occur when users are accessing the application for real over slow connections. This usually means showing things such as loading indicators when long running requests are in progress. However, when in development, the back-end servers may be located on localhost, or another machine on the local network, leading to no appreciable delay when requests are made.

To help develop and test the application, it can be useful to simulate higher latency, of say a few seconds. There are various approaches you could take to do this: Using networking tools like Fiddler to simulate slow speeds, or modifying the back-end code to delay before it sends a response. However, a quick and easy way to do it purely within the front end is to use a feature of Angular’s $http service called Response Interceptors. These let you insert handlers into the $http service provider that synchronously or asynchronously process the results of requests before they are handed back to the application.

In this case, I don’t want to change the response in any way, I just want to delay it. The interception mechanism is based on promises, just like those returned by the $http service’s methods. The handler function we register with $httpProvider takes a single promise parameter, and must also return a promise. Working with this system is one of the trickier uses of promises within Angular, and may take a little while to grasp, but it’s very effective.

The handler needs to be registered with the $httpProvider, not with the $http service itself. That means it must be done in a module config method. The implementation might look something like this:

angular.module('app', [], function($httpProvider) {

	var handlerFactory = function($q, $timeout) {
		return function(promise) {
			return promise.then(function(response) {
				return $timeout(function() {
					return response;
				}, 3000);
			}, function(response) {
				return $q.reject(response);
			});
		};
	}

	$httpProvider.responseInterceptors.push(handlerFactory);
});

You can see a working example in this Plunkr. It also demonstrates how to avoid the magic number and make the delay configurable via an httpDelayConfig service.

How it works

Even with the simplification of async that promises give us, there’s a bit to unpick here. The handlerFactory object is a factory function that just returns the actual handler function. A factory is necessary so the handler can have dependencies on services like $q that it isn’t possible to access within a module config function.

The handler function takes a single parameter called promise. This is the same as the promise object usually returned by the $http methods. If the code simply returned it without doing anything, then requests would work exactly the same as they normally do. However, I want to introduce a delay, so I register two callbacks via the promise’s then() method, and return the result of that method call. Because the result of a then() call is another promise, it will fulfill the function’s return requirement, and create a chain where the code in my callbacks is executed and their result is passed back to the application as the resolved value of the promise.

The error callback, which is the second function passed to the then() method is the simplest of the two. It simply returns a rejection message that wraps the response it receives. I don’t perform any delay, because I figure that if I’m getting errors coming back from the XHR, I’ll want to know about it right away, and debug without delays.

The success callback uses the $timeout service to delay by 3000 milliseconds. Here you can see the beauty of Angular’s adoption of promises throughout its API. The $timeout service call also returns a promise, which is resolved with the result of its callback function parameter when the timeout occurs. This means I can return have the $timeout callback return the response, and then just return the result of the $timeout call as the result of the success callback.

Remember I said that the then() method returns a promise? If a promise is resolved with a promise (as will happen when the success callback returns the $timeout promise) then it defers further until that promise is resolved. This means the promise I pass back to the application won’t be resolved until the $timeout promise resolves.

All of this can be a bit mind-bending, and you don’t need to actually understand it to use the above code. It can be dropped into your application and will delay your XHR calls without affecting them in any other way. Anything to do with asynchronicity and parallelism is generally a bit of stretch for most people’s brains, mine included. The best way to get to grips with promises seems to be to start off using them for simple things, then when you’re comfortable, move on to slightly more complicated arrangements like this one.

Polymer

At their IO 2013 conference, Google officially launched Polymer, a new library for front-end development. It might seem odd that Google are launching another library, after all, they already have Angular, GWT, Dart Web UI and Closure, why create yet another one?

However, Polymer is a bit of a different proposition that those libraries, and others like jQuery, Dojo, Knockout and Ember. Rather than creating a new API from scratch, Polymer is a collection of polyfills that attempt to implement upcoming standards, particularly those that come under the banner of Web Components. I’ve been following web components for quite a while, as it’s a technology I’m very excited about. I even created a Github project, Are We Componentized Yet? to track the gradual implementation within Chrome/Webkit. As excited as I was, the pace of their implementation within Chrome made me worry it would be a long time before they were available to use, particularly across browsers.

Google appears to have had similar concerns, and Polymer is their response. By polyfilling the necessary features, it means Web Components can be usedĀ now in modern browsers. This will help to flush out design problems with the specs, and build a groundswell of developer support that will hopefully encourage the other browsers to implement the specs.

The idea is, while other libraries grow larger and larger, Polymer should actually shrink over time, as browsers implement features that are currently polyfilled. Eventually, they will be available everywhere, and they will simply be the web platform, not a library anymore. It’s a cool idea, and I’m very hopeful it will come to fruition.

Right now, Polymer is some way off being production ready. Compared to the other library I’ve been using a lot lately, Angular, it lacks a few features, and isn’t particularly well documented. I certainly won’t be using it for any “real” projects just now, but it’s stable enough to start experimenting with.

My First Polymer Component: Fake Latin

To that end, I have created my very first web component, using the Polymer Library, called Fake Latin. It’s a custom element that generates latin placeholder text, like the “Lorem ipsum…” you often see in mock-ups and prototypes. You can download it and get full instructions on its GitHub page, but the basic idea is that, one you’ve imported the component, you simply drop a <fake-latin> tag anywhere in your HTML, and when you view the page it will insert a random latin sentence.


<fake-latin></fake-latin>

It can do more that just insert sentences. You can configure it using a “type” attribute to output paragraphs, lists, even entire structured articles. Check the docs for more info.

Although Polymer is still a little rough around the edges, creating Fake Latin really was a joy, similarly to the first time I used Knockout or Angular. It just feelsĀ right, like the library/platform is working with you, rather than against you, which was what the web platform felt like for a long time. If this is the future of web development, it’s a good one.

Unfortunately, the path to native Web Components nirvana is by no means certain. The specs are still far from finalised, and the size and complexity of the features involved means it will be a long time before they are fully implemented across all browsers, if they ever are. Webkit, for example, just removed their implementation of Shadow DOM (it was developed by Google, and had no maintainer after they left the project to create Blink). Enough interest from developers and additional implementations by Mozilla (in progress) and Microsoft (possible) might hopefully encourage the Webkit contributors to start a new implementation of Web Components, but time will tell.

However, worries about browser implementations shouldn’t stop people checking out Polymer and experimenting with it. If nothing else, it will give your hope for just how good the web platform could be.

Attempt to transcribe the lyrics to Katrien by Mogwai

I’ve always loved the song Katrien by Mogwai, from their first album Mogwai Young Team. It’s often classed as an instrumental, but there are spoken vocals, although they are low in the mix and are frequently drowned out almost completely by the music. According to the band themselves, the words are then-member Brendan O’Hare “talking shite about yetis or something like that, don’t ask me why”. O’Hare was later kicked out of the band, apparently for talking during an Arab Strap performance. Rock and roll.

Anyway, despite them clearly being rambly nonsense, I’ve always been curious as to what the words spoken during Katrien actually are, and since nobody else on the internet seems to have attempted to properly transcribe them, the below represents my best effort. The parts I’ve found so far inaudible or unintelligible are indicated with an ellipsis, and bear in mind that that’s probably about 70% of the song, but I’ve worked out enough to get a flavour of the whole.

I’ve been reading about and looking at pictures of Yetis from various parts of the world. Pakistan, China and Malaysia. I always look at these things with more than a sense of skepticism. But I remember thinking, oh my god, this seems (almost unreal?) …

In the distance (pauline chews the nose?) off (his/its?) face … half tempted, I suppose. But unfortunately … trying too hard… Anyway under the cover of a … <fart noise>, I made a beeline for the door.

Last time I was in town … I met an interesting man called Frederick, told me many people die too late and a few too early. Should try to let them die at the right time. Don’t become a domestic animal, herd animal, a sick human animal … Death is no …

New religions follow … as that was taken over by people. Downstairs …

eyes been drawn … This is the point of genesis for all human life in the universe. Here … planets for us to populate … descended from a … ancestor … he smiled … expanding throughout the universe … the past, the future … extremely (likely?)

… can no longer see or hear or feel anything. I see and hear and feel everything simultaneously.

I awake in the corridor, Frederick smiling, standing over me. “What did I tell you?” he said. “How did you know?” “How do you know?” He just smiled and walked off. And from where I was lying I could see the (satin?) exterior of the …

The above was transcribed via careful repeated listens with headphones and much fiddling of the equalizer. If anyone with better audio equipment or processing skillz can provide any further suggestions, let me know in the comments. Unfortunately some bits, particularly the latter section where there seems to be multiple voices talking at once, will probably never be intelligible without hearing an isolated vocal from a master recording.