Having a loop in angular with $timeout

When first starting out with angular I found myself having logic in my controllers which is not really what a controller id for. Loops, and app login in general, is best placed inside services made with module.factory, or one of the other options for doing so.

In this post I will be covering how I go about making a loop in a service, and using a controller to update the view with the latest data from that service.

$timeout example made with module.factory.

For my example I will be making a service with module.factory called loop and use that in a controller.

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
var app = angular.module('app', []);
app.factory('loop', function ($timeout) {
// a state
var state = {
start: new Date(),
time: 0,
count: 0,
ms: 250
},
// loop
loop = function () {
var now = new Date();
state.time = now - state.start;
state.count += 1;
$timeout(loop, state.ms);
};
// start loop
loop();
// api
return {
// grab the current state
grab: function (func) {
return state;
}
};
});
app.controller('fact-control', function ($scope, loop) {
// reference the state object
var state = loop.grab();
$scope.state = state;
});

The grab method returns a reference to the internal state object. Because it’s a reference I do not have to do anything weird in my controller. All I have to do is just simply set it to a property in $scope, and use it in my view.

1
2
3
4
5
6
7
8
<div ng-app="app" ng-controller="fact-control" >
<p>start time {{state.start}}</p>
<p>time {{state.time}}</p>
<p>count every {{state.ms}} ms</p>
<p>count: {{state.count}}</p>
</div>