Reputation: 111
I want to return the value from setInterval() function which is called from html file.
I know that the actual function is not returning anything and that's why the value is not being shown. But how can I return the value from an asynchronous function.
Here's the code:
.ts:
data = [
{
game: "A vs B",
timeLeft: 123456
},
{
game: "C vs D",
timeLeft: 342514
},
{
game: "A vs C",
timeLeft: 654789
},
{
game: "B vs D",
timeLeft: 978456
}
];
clearTimeIntervalVar: any;
countdownTime(seconds: number) {
let hr: any = Math.floor(seconds / 3600);
let min: any = Math.floor((seconds % 3600) / 60);
let sec: any = Math.floor((seconds % 3600) % 60);
this.clearTimeIntervalVar = setInterval(() => {
sec--;
if (sec === 0) {
if (min !== 0) {
min--;
}
sec = 60;
if (min === 0) {
hr--;
min = 59;
}
}
return (
("00" + hr).slice(-2) +
" : " +
("00" + min).slice(-2) +
" : " +
("00" + sec).slice(-2)
);
}, 1000);
}
.html:
<div class="flex">
<div class="width-50">Games</div>
<div class="width-50">Time Left</div>
</div>
<div class="flex" *ngFor="let item of data">
<div class="width-50">{{ item.game }}</div>
<div class="width-50">{{ countdownTime(item.timeLeft) }}</div>
</div>
Here's the stackblitz link.
Thanks in advance.
Upvotes: 1
Views: 357
Reputation: 685
Angular Pipes are your friends !
@Pipe({ name: "countdown" })
export class CountdownPipe implements PipeTransform {
transform(time: number) {
return interval(1000).pipe(map(i => (time - i) * 1000));
}
}
<div class="width-50">{{ item.timeLeft | countdown | async | date: "HH:mm:ss": "GMT" }}</div>
https://stackblitz.com/edit/angular-ivy-uiluwk?file=src%2Fapp%2Fapp.component.html
My idea is first of all create an "observable pipe" which decrease your "time" value from seconds to ms. Then piping it with "async" making it readable by the template and then piping again to Date with autoformatting on GMT time.
I didn't implemented what happens when the countdown is done but you can do it in many ways with a condition in the observable with "until" operator or in your template with a ternary.
Observables are very powerfull and well implemented with Angular. https://www.learnrxjs.io/ can be very helpfull to master RxJs.
Ask me for any further questions
Upvotes: 0
Reputation: 26370
In your view, simply display {{ item.timeLeft }}
, or {{ secondsToTime(item.timeLeft) }}
, a utility that converts seconds to HH:mm:ss. In your component, write an interval that updates every item.timeleft
every second.
HTML :
<div class="flex" * ngFor="let item of data" >
<div class="width-50" > {{ item.game }}</div>
<div class="width-50" > {{ secondsToTime(item.timeLeft) }}</div>
</div>
TS:
data = [
{game: "A vs B",timeLeft: 123456},
{game: "C vs D",timeLeft: 342514},
{game: "A vs C",timeLeft: 654789},
{game: "B vs D",timeLeft: 978456}
];
clearTimeIntervalVar: any;
launchInterval(){
setInterval(() => {
for (let item of data) item.timeLeft--;
, 1000})
}
secondsToTime(seconds: number) : string{
let convertedTime;
// Here convert secons to HH:mm:ss
return convertedTime
}
Upvotes: 1