AngularJS polling service

A while ago, I had to write a polling service in AngularJS. For this service, there were three main requirements:

poll the backend every x ms until the expected result has been attained

the service has to timeout after a set period of time

one should be able to stop the polling

The polling and the timeout were fairly trivial to implement. There was only one gotcha. If you’re using Protractor for e2e testing, you have to use $interval instead of $timeout. Protractor has issues figuring out when AngularJS is done with its work when you use $timeout. With the $interval service it behaves like expected.

The tricky part for me turned out to be the third requirement. How do you cancel the polling? Eventually, I figured out that it had to be done through cancelling the $interval/$timeout.

To summarise, here is an example that outlines what I’ve come up with:

An AngularJS Polling Service

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

(function(){

'use strict';

angular

.module('it.jdev.examples')

.factory('PollingService',PollingService);

PollingService.$inject=['$q','$http','$interval'];

functionPollingService($q,$http,$interval){

varcurrentlyRunningRequest=null;

varapi={

getResults:getResults,

cancel:cancel

};

returnapi;

functioncancel(){

if(currentlyRunningRequest){

$interval.cancel(currentlyRunningRequest);

}

currentlyRunningRequest=null;

}

functiongetResults(){

vardeferred=$q.defer();

cancel();// Cancel any previous request;

vargetData=function(){

$http.get('http://examples.jdev.it/my_example_service').then(

function(data){

if(data.myAttribute==='Value I\'m waiting for'){

deferred.resolve(data);

}elseif(hasTimedOut()){

deferred.reject('Timed out');

}else{

currentlyRunningRequest=$interval(getData,1000,1);// retry in one second