Aravind
Aravind

Reputation: 41533

Custom Pipe | filter for calculating relative time in angular2

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

Upvotes: 2

Views: 3037

Answers (2)

danday74
danday74

Reputation: 56936

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)
}

Upvotes: 2

Aravind
Aravind

Reputation: 41533

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

Upvotes: 10

Related Questions