Custom Pipe | filter for calculating relative time in angular2

2.8k Views Asked by At

During the learning process, I came across Creation of Custom Pipe, so I thought this will help.

2

There are 2 best solutions below

1
On BEST ANSWER

Below is the code for custom pipe.

import{PipeTransform,Pipe} from '@angular/core';

@Pipe({
    name:'relativeTime'
})

export class RelativeTimeFilterPipe implements PipeTransform{

    transform(inputDate:string):string{
        var current = new Date().valueOf();
        var input = new Date(parseInt(inputDate)).valueOf();
        var msPerMinute = 60 * 1000;
        var msPerHour = msPerMinute * 60;
        var msPerDay = msPerHour * 24;
        var msPerMonth = msPerDay * 30;
        var msPerYear = msPerDay * 365;

        var elapsed = current - input;

        if (elapsed < msPerMinute) {
            return Math.round(elapsed / 1000) + ' seconds ago';
        }

        else if (elapsed < msPerHour) {
            return Math.round(elapsed / msPerMinute) + ' minutes ago';
        }

        else if (elapsed < msPerDay) {
            return Math.round(elapsed / msPerHour) + ' hours ago';
        }

        else if (elapsed < msPerMonth) {
            return 'approximately ' + Math.round(elapsed / msPerDay) + ' days ago';
        }

        else if (elapsed < msPerYear) {
            return 'approximately ' + Math.round(elapsed / msPerMonth) + ' months ago';
        }

        else {
            console.log('inside the if condition', elapsed);
            return 'approximately ' + Math.round(elapsed / msPerYear) + ' years ago';
        }

    }
}

LIVE DEMO

2
On

Here's an async relative date pipe for you. It updates relative time as you watch your screen and its not even an impure pipe, making it much faster! Another great thing is that the relative time updates all occur at the same time by using a cron scheduler.

import { OnDestroy, Pipe, PipeTransform } from '@angular/core'
import { timeAgo } from '../../../utils/date-utils'
import { BehaviorSubject } from 'rxjs'
import * as schedule from 'node-schedule'

@Pipe({name: 'timeAgo'})
export class TimeAgoPipe implements PipeTransform, OnDestroy {

  sub: BehaviorSubject<string>
  job: schedule.Job
  date: Date

  constructor() {
    this.sub = new BehaviorSubject<string>(null)
    this.job = schedule.scheduleJob('*/10 * * * * *', () => { // updates every 10 secs at 1:10 1:20 1:30 etc
      if (this.date) this.sub.next(timeAgo(this.date))
    })
  }

  transform(date: Date | number): BehaviorSubject<string> {
    setTimeout(() => {
      this.date = new Date(date)
      this.sub.next(timeAgo(this.date))
    })

    return this.sub
  }

  ngOnDestroy(): void {
    this.job.cancel()
  }
}

template usage looks like this:

<span>{{ activity.date | timeAgo | async }}</span>

And here's the timeAgo function:

import TimeAgo from 'javascript-time-ago'
import en from 'javascript-time-ago/locale/en'

TimeAgo.addDefaultLocale(en)
const ago = new TimeAgo()

export const timeAgo = (date) => {
  return ago.format(date)
}