Tech Incent
Angular Angular Pipe

Angular Date as ago (minutes / hours / days / months / years ago) pipe

In this article, I will create a user-friendly angular date pipe, Date will transform as human-readable (minutes/hours/days/months / years) ago.

For example, I have a list of objects that look like …

[
  {
    name: "node 1",
    daemonSetCount: 10,
    deploymentCount: 200,
    id: "602d7a789e59c200010bd6a2",
    creationTimestamp: "2021-02-17T16:24:21Z"
  },
  {
    name: "node 2",
    daemonSetCount: 10,
    deploymentCount: 200,
    id: "602d7a789e59c200010bd7f1",
    creationTimestamp: "2021-01-17T15:24:21Z"
  },
  {
    name: "node 3",
    daemonSetCount: 30,
    deploymentCount: 40,
    id: "602d7a789e59c200010bd9t4",
    creationTimestamp: "2021-04-17T18:30:21Z"
  },
  {
    name: "node 4",
    daemonSetCount: 5,
    deploymentCount: 17,
    id: "602d7a789e59c200010bd0b8",
    creationTimestamp: "2021-06-17T20:39:21Z"
  }
]

So I am going to loop this node in my node.component.html file.

<div class="container mx-auto">
    <table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
        <!-- Name Column -->
        <ng-container matColumnDef="name">
            <th mat-header-cell *matHeaderCellDef> Name </th>
            <td mat-cell *matCellDef="let node"> {{node.name | titlecase}} </td>
        </ng-container>

        <!-- Deplyment Column -->
        <ng-container matColumnDef="deplyment">
            <th mat-header-cell *matHeaderCellDef> Deplyment </th>
            <td mat-cell *matCellDef="let node"> {{node.deploymentCount}} </td>
        </ng-container>

        <!-- Daemonset Column -->
        <ng-container matColumnDef="daemonset">
            <th mat-header-cell *matHeaderCellDef> Daemonset </th>
            <td mat-cell *matCellDef="let node"> {{node.daemonSetCount}} </td>
        </ng-container>

        <!-- Date Column -->
        <ng-container matColumnDef="created">
            <th mat-header-cell *matHeaderCellDef> Created </th>
            <td mat-cell *matCellDef="let node"> {{node.creationTimestamp}} </td>
        </ng-container>

        <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
        <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
    </table>
</div>

Here is the display, you can see the timestamp is not a human-readable and user-friendly view. it’s ugly.

date-as-timestamp
Timestamp time view

let’s use angular date build-in pipe. {{ node.creationTimestamp | date }}. it will display human-readable. But it’s not a good approach as well as not user-friendly.

data-as-date
Date pipe view

Build our custom date as ago pipe

Let’s generate our dateAsAgo pipe user terminal

ng g p shared/dateAsAgo --export

Note: If you are using the SharedModule approach, then it’s fine. otherwise, make sure you setting up properly. you can see –export option also added. it will make the dateAsAgo pipe full project usable.

now you can see two files generate.

data-as-ago-generate-file

Now implement your date-as-ago.pipe.ts file with this function

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

@Pipe({
  name: 'dateAsAgo'
})
export class DateAsAgoPipe implements PipeTransform {
  transform(value: any, ...args: unknown[]): unknown {
    if (!value) { return 'a long time ago'; }

    let time = (Date.now() - Date.parse(value)) / 1000;

    if (time < 10) {
      return 'just now';
    } else if (time < 60) {
      return 'a moment ago';
    }

    const divider = [60, 60, 24, 30, 12];
    const string = [' second', ' minute', ' hour', ' day', ' month', ' year'];

    let i;
    for (i = 0; Math.floor(time / divider[i]) > 0; i++) {
      time /= divider[i];
    }
    const plural = Math.floor(time) > 1 ? 's' : '';

    return Math.floor(time) + string[i] + plural + ' ago';
  }
}

Finally, you see the actual view

data-as-ago
DateAsAgo pipe View

Related posts

How to add bootstrap 5 in the angular application?

Sajal Mia

Code Syntax Highlighter Angular With Prism.js

Sajal Mia

Angular Pure Bootstrap 5 Sidenav

Sajal Mia