Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reevaluate filter on timer in AngularJS

I have a filter that I use to display relative time i.e. 5 mins ago. I want to be able to make this filter (or write a directive) to re-evaluate this every minute. How can I do this?

JS Filter

m.filter('relativeTime', function () {
    return function (input, showAgo) {
        if (typeof showAgo == "undefined") {
            showAgo = true;
        }

        var dateMoment = input;
        if (typeof input == "string") {
            dateMoment = moment(input);
        }

        return dateMoment.fromNow(showAgo);
    };
});

HTML

<span class="relativeTime">{{activity.Time | relativeTime }}</span>
like image 520
Chris Avatar asked Jul 15 '15 10:07

Chris


1 Answers

Although it's possible to create a stateful filter, the documentation strongly advices to make only stateless and idempotent filters. That's why a directive is a better idea here.

The principle is simple: when the directive is compiled, create a timer that will refresh the value every minute. The $interval service is perfect for that goal. However, as stated by the documentation, don't forget to destroy it when you don't need it any more.

MyApp.directive('relativeTime', function ($interval) {
    return {
        scope: {
            time: '=',
        },
        template: '<div>{{relativeTime}} secondes ago.</div>',
        link: function ($scope) {
            $scope.relativeTime = 0;

            var intervalPromise = $interval(function () {
                ++$scope.relativeTime;
            }, 1000);

            $scope.$watch('time', function (time) {
                var currentTime = new Date();
                $scope.relativeTime = Math.round((currentTime.getTime() - time.getTime()) / 1000);
            });

            $scope.$on('$destroy', function () {
                $interval.cancel(intervalPromise);
            });
        },
    };
});

Fiddle

For demonstration purposes, this directive is very simple and updated every second. But it's shouldn't be difficult to adapt it to your use case and in particular to your date.fromNow() function.

like image 102
Blackhole Avatar answered Oct 11 '22 02:10

Blackhole