Use jQuery timeago or momentjs and AngularJS together

I want to use timeago plugin to make dates look nicer. The problem is that these dates are fetched via AngularJS from the REST dynamically. So, when I attach this jQuery plugin to my page, it just doesn't process it.

So, how to better do such things? I would be happy to run without jQuery at all if possible.

I would use momentjs - http://momentjs.com/ - it has no dependencies.

Then you can just create a filter called 'timeAgo' or 'fromNow'. You should probably call it fromNow because that's what momentjs calls it:

angular.module('myApp').filter('fromNow', function() {
  return function(date) {
    return moment(date).fromNow();
  }
});

Then you would just use simple data binding in your view:

<p>Pizza arrives {{pizzaArrivalDate | fromNow}}</p>

If you really wanted to use the jQuery plugin, you would probably have to write a directive. But that way of doing it is bad because it links your data to a DOM element. The way I put above seperates data from DOM which is the angular way. And it's pretty :-D

You can use the am-time-ago directive from angular-moment module (which is based on momentjs).

It does not require jQuery, and the time get updated as time progresses. Example:

<span am-time-ago="lastLoginTime"></span>

The content of the above span will be replaced with a relative time string, for example "2 hours ago", and will be automatically updated as time progresses.

If you need jQuery, writing a directive/filter is the way to go.

app.directive("timeAgo", function($compile) {
  return {  
    restrict: "C",
    link: function(scope, element, attrs) {
      jQuery(element).timeago();
    }
  };
});

app.filter("timeAgo", function() {
  return function(date) {
    return jQuery.timeago(date); 
  };
});

Directive and/or Filter (jsbin)

moment.js is the best choice. I have created a generic moment filter that allow you to use any moment formatting method.

angular.module('myApp', [])
  .filter('moment', [
    function () {
      return function (date, method) {
        var momented = moment(date);
        return momented[method].apply(momented, Array.prototype.slice.call(arguments, 2));
      };
    }
  ]);

Use it like

<div>{{ date | moment:'fromNow' }}</div>
<div>{{ date | moment:'calendar' }}</div>

You can checkout it in action here http://jsfiddle.net/gregwym/7207osvw/