I'm a little new to RXJS so not really sure how the Pipe and Map are being used here, but the line below never gets called. It's inside a pipe and map.
return this.msToTime(this.getMsDiff(futureDate));
On the screen, I just see [object, object], instead of the countdown timer.
Here is the git repo for this Angular pipe.
I've created a Stacklitz here that shows no output on the screen. If you uncomment out the pipe map section you will see nothing but [object, object] on the screen.
EDIT - If I replace the pipe and map with a subscribe like below I can see the incremental values in console.log, but nothing shows on the screen.
const source = timer(0, 1000);
const abc = source.subscribe(val => {
const timeRemaining = this.msToTime(this.getMsDiff(futureDate));
console.log(timeRemaining);
return timeRemaining;
});
<span class="float-right yb-color">{{event.datePendingUtc | timeRemaining}}</span>
/**
* @param futureDate should be in a valid Date Time format
* e.g. YYYY-MM-DDTHH:mm:ss.msz
* e.g. 2021-10-06T17:27:10.740z
*/
public transform(futureDate: string): Observable < string > {
/**
* Initial check to see if time remaining is in the future
* If not, don't bother creating an observable
*/
if (!futureDate || this.getMsDiff(futureDate) < 0) {
return null;
}
return timer(0, 1000).pipe(
map(() => {
// never gets hit
return this.msToTime(this.getMsDiff(futureDate));
})
);
}
/**
* Gets the millisecond difference between a future date and now
* @private
* @param futureDate: string
* @returns number milliseconds remaining
*/
private getMsDiff = (futureDate: string): number => ( (new Date(futureDate)) - Date.now());
/**
* Converts milliseconds to the
*
* @private
* @param msRemaining
* @returns null when no time is remaining
* string in the format `HH:mm:ss`
*/
private msToTime(msRemaining: number): string | null {
if (msRemaining < 0) {
console.info('No Time Remaining:', msRemaining);
return null;
}
let seconds: string | number = Math.floor((msRemaining / 1000) % 60),
minutes: string | number = Math.floor((msRemaining / (1000 * 60)) % 60),
hours: string | number = Math.floor((msRemaining / (1000 * 60 * 60)) % 24);
/**
* Add the relevant `0` prefix if any of the numbers are less than 10
* i.e. 5 -> 05
*/
seconds = (seconds < 10) ? '0' seconds : seconds;
minutes = (minutes < 10) ? '0' minutes : minutes;
hours = (hours < 10) ? '0' hours : hours;
return `${hours}:${minutes}:${seconds}`;
}
CodePudding user response:
Move msToTime
function inside rxjs map
return source.pipe(
map(_ => this.msToTime(this.getMsDiff(futureDate)))
);
In template you see [object, object] because you are returning Observable from filter
pipe, so use Async to subscribe it like
<div> date countdown: {{ '2021-10-06T17:27:10.740z' | filter | async }} </div>