I am trying to create a 'time ago' pipe for my Angular 2 application.
It should transform a date to a string such as '5 minutes ago' or '60 seconds ago'. It works nicely so far, but it doesn't update after the first calculation. If the given date is for example 5 seconds ago, it displays '5 seconds ago' but never changes after that.
I have already tried setting the pipes 'pure' value to false but that didn't help.
Here is my code:
import {Pipe, PipeTransform} from 'angular2/core';
@Pipe({
name: 'messageTime',
pure: false
})
export class MessageTimePipe implements PipeTransform {
transform(value: Date, []): string {
var result: string;
// current time
let now = new Date().getTime();
// time since message was sent in seconds
let delta = (now - value.getTime()) / 1000;
// format string
if (delta < 10) {
result = 'jetzt';
} else if (delta < 60) { // sent in last minute
result = 'vor ' + Math.floor(delta) + ' Sekunden';
} else if (delta < 3600) { // sent in last hour
result = 'vor ' + Math.floor(delta / 60) + ' Minuten';
} else if (delta < 86400) { // sent on last day
result = 'vor ' + Math.floor(delta / 3600) + ' Stunden';
} else { // sent more than one day ago
result = 'vor ' + Math.floor(delta / 86400) + ' Tagen';
}
return result;
}
}
I'm using the filter like this:
TypeScript:
import {Component, Input} from 'angular2/core';
import {MessageTimePipe} from '../../pipes/message-time.pipe';
@Component({
selector: 'message-item',
pipes: [MessageTimePipe],
templateUrl: 'build/components/message-item/message-item.component.html'
})
export class MessageItemComponent {
@Input()
message: JSON;
date: Date;
ngOnInit() {
this.date = new Date(2016, 3, 16, 12, 49, 10);
}
}
HTML:
<p class="time">
{{ date | messageTime }}
</p>
The following library does equivalent job in English and could be forked to change the language or support different ones:
https://www.npmjs.com/package/time-ago-pipe
npm install time-ago-pipe --save
Then in the @NgModule you want to use it in:
import {TimeAgoPipe} from 'time-ago-pipe'
@NgModule({
imports: [... etc ...],
declarations: [AppComponent, ...etc..., TimeAgoPipe],
bootstrap: [AppComponent]
})
And in the template:
<span>{{your_date | timeAgo}}</span>
Finally got it working, quite challenging and requires interval tweaking:)
import {Pipe, ChangeDetectorRef} from 'angular2/core';
import {Observable} from 'rxjs/Observable';
import {AsyncPipe} from 'angular2/common';
@Pipe({
name: 'messageTime',
pure: false
})
export class MessageTimePipe extends AsyncPipe
{
value:Date;
timer:Observable<string>;
constructor(ref:ChangeDetectorRef)
{
super(ref);
}
transform(obj:any, args?:any[]):any
{
if (obj instanceof Date)
{
this.value = obj;
if(!this.timer)
{
this.timer = this.getObservable();
}
return super.transform(this.timer, args);
}
return super.transform(obj, args);
}
private getObservable()
{
return Observable.interval(1000).startWith(0).map(()=>
{
var result:string;
// current time
let now = new Date().getTime();
// time since message was sent in seconds
let delta = (now - this.value.getTime()) / 1000;
// format string
if (delta < 10)
{
result = 'jetzt';
}
else if (delta < 60)
{ // sent in last minute
result = 'vor ' + Math.floor(delta) + ' Sekunden';
}
else if (delta < 3600)
{ // sent in last hour
result = 'vor ' + Math.floor(delta / 60) + ' Minuten';
}
else if (delta < 86400)
{ // sent on last day
result = 'vor ' + Math.floor(delta / 3600) + ' Stunden';
}
else
{ // sent more than one day ago
result = 'vor ' + Math.floor(delta / 86400) + ' Tagen';
}
return result;
});
};
}
The accepted answer can not work with angular 7+.
I followed this answer and customize for Vietnamese.
https://stackoverflow.com/a/61341940/4964569
I share for whom concern.
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({
name: 'dateAgo',
pure: true
})
export class TimePipe implements PipeTransform {
transform(value: any, args?: any): any {
if (value) {
const seconds = Math.floor((+new Date() - +new Date(value)) / 1000);
if (seconds < 29) // less than 30 seconds ago will show as 'Just now'
return 'vừa mới đăng';
const intervals = {
'năm': 31536000,
'tháng': 2592000,
'tuần': 604800,
'ngày': 86400,
'giờ': 3600,
'phút': 60,
'giây': 1
};
let counter;
for (const i in intervals) {
counter = Math.floor(seconds / intervals[i]);
if (counter > 0){
return counter + ' ' + i + ' trước'; // singular (1 day ago)
}
}
}
return value;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With