Create countdown clock using angularJS services

In my previous post Create a ticking clock using angularJS timeout service I showed how to create a clock. In this post I am going to discuss how to create a count down clock. In addition I will also show how to write a custom angularJS service.

Sample implementation

Instead of showing some static image, here is the live example of countdown clock prototype that I created.

Current Auctions
{{init(auction)}}

{{auction.Name}}

Bids placed: {{auction.NumberOfBids}}
Current Bid: {{auction.CurrentBid | currency}}
Auction ends in

{{auction.remainingTime|durationview}}

The above panel is a pseudo auction page. It gets auction item list from server every 10s to refresh listing and then it has second timer ticking every 1s to show remaining time to auction end time. The following HTML code snippet demonstrates how this panel has been built using angularJS binding with model.

    <div ng-controller="AuctionItemsController">
      <div class="row">
       <div class="col-xs-5" ng-repeat="auction in auctions">
                                        {{init(auction)}}
       <div class="panel panel-info">
        <div class="panel-body">
         <h3>{{auction.Name}}</h3>
         <div><strong>Bids placed:</strong> {{auction.NumberOfBids}}</div>
         <div><strong>Current Bid:</strong> {{auction.CurrentBid | currency}}</div>
         <div><strong>Auction ends in</strong></div>
         <div><h3 class="text-primary"> {{auction.remainingTime|durationview}}</h3></div>
        </div>
       </div>
      </div>
     </div>
    </div>

Following sections will discuss different components of this implementation.

angularJS controller

The following controller is used to execute following tasks:

  • Get list of auction items using $http service.
  • Run a timer on 1s interval using $timeout service to tick the clock
  • Run a timer on 10s interval using $timeout service to refresh aucion item list
ByteBlocksApp.controller("AuctionItemsController", 
 ['$scope', '$http', '$timeout', 'datetime', function ($scope, $http, $timeout, datetime) {
    $scope.apiController = PortalSettings.baseUrl + "/api/auction";
    var getAuctionItems = function () {
        $http({ method: 'GET', url: $scope.apiController + '/GetAuctionItems', params: { maxItems: 5 } }).
        success(function (data, status, headers, config) {
            processAuctionItems(data);
            $scope.auctions = data;
            $timeout(getAuctionItems, 10000);
        }).
        error(function (data, status, headers, config) {
            //TODO: log this error
            $timeout(getAuctionItems, 10000);
        });
    };
    var tick = function () {
        $scope.currentTime = moment();
        processAuctionItems($scope.auctions);
        $timeout(tick, 1000);
    }
    var processAuctionItems = function (data) {
        angular.forEach(data, function (item) {
            item.remainingTime = datetime.getRemainigTime(item.AuctionEndDateTime);
        });
    }
    $scope.currentTime = moment();
    getAuctionItems();
    $timeout(tick, 1000);
    $timeout(getAuctionItems, 10000);
}]);

Custom angularJS service for date manipulation

In this controller I have injected a custom service datetime. This service is used to provide date and time manipulation services.

 ByteBlocksApp.factory('datetime', ['$timeout', function ($timeout) {
    var duration = function (timeSpan) {
        var days = Math.floor(timeSpan / 86400000);
        var diff = timeSpan - days * 86400000;
        var hours = Math.floor(diff / 3600000);
        diff = diff - hours * 3600000;
        var minutes = Math.floor(diff / 60000);
        diff = diff - minutes * 60000;
        var secs = Math.floor(diff / 1000);
        return { 'days': days, 'hours': hours, 'minutes': minutes, 'seconds': secs };
    };
    function getRemainigTime(referenceTime) {
        var now = moment().utc();
        return moment(referenceTime) - now;
    }
    return {
        duration: duration,
        getRemainigTime: getRemainigTime
    };
}]);

Custom angularJS filter

To display remaining time of countdown clock, I have created a custom filter to display it in more meaningful way.

ByteBlocksApp.filter('durationview', ['datetime', function (datetime) {
    return function (input, css) {
        var duration = datetime.duration(input);
        return duration.days + "d:" + duration.hours + "h:" + duration.minutes + "m:" + duration.seconds + "s";
    };
}]);

As you can see that I have managed to create a decent framework to build a pseudo auction item display page that shows a countdown clock.

comments powered by Disqus

Search

Social

Weather

Monthly Posts