Reputation: 233
I followed this link to create my own time ago pipe: Angular 2 "time ago" pipe
but when I injected and used it, I saw the error:
Template parse errors: The pipe 'timeAgo' could not be found
Below is my code, please help me to resolve this issue, many thanks!!
timeAgo.pipe.ts
import { Pipe, ChangeDetectorRef } from '@angular/core';
import { AsyncPipe } from '@angular/common';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/interval';
import 'rxjs/add/operator/startWith';
@Pipe({
name: 'timeAgo',
pure: false
})
export class TimeAgoPipe extends AsyncPipe {
value: Date;
timer: Observable<string>;
constructor(private 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 this.timer;
}
return this.transform(obj, args);
}
private getObservable(){
const INTERVAL = 1000 * 45;
const ONE_MINUTE = 60;
const ONE_HOUR = 60 * 60;
const ONE_DAY = 60 * 60 * 24;
const ONE_MONTH = 60 * 60 * 24 * 30;
const ONE_YEAR = 60 * 60 * 24 * 30 * 12;
return Observable.interval(INTERVAL).startWith(0).map(() => {
// current time
let now = Date.now();
// time since message was sent in seconds
let delta = (now - this.value.getTime()) / 1000;
// format string
if(delta < ONE_MINUTE) {
return 'just now';
}
if(delta < ONE_HOUR) {
return Math.floor(delta / ONE_MINUTE) + 'min(s) ago';
}
if(delta < ONE_DAY) {
return Math.floor(delta / ONE_HOUR) + 'hour(s) ago';
}
if(delta < ONE_MONTH) {
return Math.floor(delta / ONE_DAY) + 'day(s) ago';
}
if(delta < ONE_YEAR) {
return Math.floor(delta / ONE_MONTH) + 'month ago';
}
});
}
}
main.ts
import { bootstrap } from '@angular/platform-browser-dynamic';
import { enableProdMode, provide, PLATFORM_PIPES } from '@angular/core';
bootstrap(AppComponent, [
APP_ROUTER_PROVIDERS,
provide(PLATFORM_PIPES, {
useValue: [TimeAgoPipe],
multi: true
})
]);
post.component.html
<ul *ngIf="posts">
<li *ngFor="let post of posts">
{{ post.created_at | timeAgo}}
</li>
</ul>
Upvotes: 5
Views: 4979
Reputation: 23
Even though I added MomentModule as a global import, I put
import { MomentModule } from 'angular2-moment';
and put I MomentModule like so
...
imports: [
...,
MomentModule,
...,
]
under the corresponding *.module.ts, in your case it would be post.component.module.ts
as advised in the link below
https://stackoverflow.com/questions/47182015/template-parse-the-pipe-could-not-be-found#=
Upvotes: 0
Reputation: 35761
This occurs because your TimeAgoPipe
inherits from AsyncPipe
. I don't know about the behavior during the Angular2 beta builds, but Angular 2.2.x consistently fails to find inherited @Component
, @Pipe
and @Directive
classes during template compilation for me.
It seems there are some very good reasons Angular2 doesn't support component inheritance: https://github.com/angular/angular/issues/7968
If you're looking for a TimeAgoPipe
compatible with Angular 2.2, have a look at my answer here or have a direct look at the gist.
Upvotes: 2
Reputation: 16758
It seems to be that PLATFORM_PIPES
is being deprecated (https://github.com/angular/angular/blob/master/CHANGELOG.md).
You can use the method provided in this article to set global pipe: https://medium.com/@jecelynyeen/angular2-platform-pipes-globally-available-custom-pipe-will-be-deprecated-soon-c6ad16812c11#.ntmim1t9x
bootstrap(AppComponent, [
provide(CompilerConfig, {
useValue: new CompilerConfig({
platformPipes: [...COMMON_PIPES, TimeAgoPipe],
platformDirectives: [...COMMON_DIRECTIVES],
genDebugInfo: true
})
}),
]);
Upvotes: 1