Reputation: 2381
I am using the moment
library to create a human readable timer in Angular through a pipe. Basically my pipe takes a date and returns something like "5 minutes ago" instead of "2021-01-05 10:45AM".
The data in my list is static, the date/time for each item being loaded from a database:
ts:
tasks = [{dueDate: "2021-01-05 10:45AM", message: "Put the bins out"},
{dueDate: "2021-01-05 11:30AM", message: "Meeting with Jack"}];
html:
<div *ngFor="let task of tasks">
{{task.message}} - {{task.dueDate | dateh}}
</div>
result:
Put the bins out - 5 minutes ago
Meeting with Jack - in 50 minutes
I want to create a timer that will refresh the UI, so that in one minute we get:
Put the bins out - 6 minutes ago
Meeting with Jack - in 49 minutes
Without reloading the data or refreshing every other component on the page. I have a 30 second timer created with ngrx:
this.timerSub = timer(30000, 30000).subscribe((d) =>
console.log("Timer is now", d)
);
But because the data hasn't actually changed (just the pipe transform will now return a different string), I can't seem to get the component display to detect anything is different.
What is the best way to force the UI to re-run the pipe transform and update the display?
Upvotes: 0
Views: 198
Reputation: 916
Based on this angular documentation, You can convert your pipe to an impure pipe. Then the change detection should fire.
To execute a custom pipe after a change within a composite object, such as a change to an element of an array, you need to define your pipe as impure to detect impure changes. Angular executes an impure pipe every time it detects a change with every keystroke or mouse movement.
@Pipe({
name: 'yourPipeName',
pure: false
})
While an impure pipe can be useful, be careful using one. A long-running impure pipe could dramatically slow down your app.
Upvotes: 1