Reputation: 47
I have a simple countdown timer in angular 4
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/timer';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';
countDown;
counter = 60;
enableButton:boolean = false;
this.countDown = Observable.timer(0,1000).take(this.counter).map(() => --
this.counter);
I want to make enableButton boolean true when this observable has been completed.
How should I write that code? Please Help
Here is a plunker link, which I am using in my project https://plnkr.co/edit/TWMIEd1UykUdUC37qyFK?p=preview
Upvotes: 4
Views: 3931
Reputation: 28738
In the view:
<button [disabled]="counter !== 0">OK</button>
and in the class:
countDown;
counter = 10; // change accordingly
tick = 1000;
constructor() {
this.countDown = Observable.timer(0, this.tick)
.take(this.counter)
.map(() => --this.counter)
}
Upvotes: 4
Reputation: 146350
You can utilize scan and async to your advantage:
@Component({
selector: 'my-app',
template: `
<div>
<h1>Countdown timer</h1>
<h2>{{countDown | async}}</h2>
<button [disabled]="(countDown | async) === 0">My button</button>
</div>
`,
})
export class App {
countDown;
counter = 10;
constructor() {
this.countDown = Observable.timer(0,1000)
.scan((current, next) => this.counter - next)
.takeWhile(counter => counter >= 0);
}
}
Here is the live version: https://plnkr.co/edit/bKESzNK1wqbtPmQk4TUT?p=preview
So instead of updating the global counter you use scan to keep count of a local version (as the timer returns numbers in sequence)
You can utilize the .takeWhile
operator
this.countDown = Observable.timer(0,1000)
.take(this.counter)
.map(() => --this.counter)
.takeWhile(counter => counter >= 0);
Here is the updated plnkr: https://plnkr.co/edit/Z6K5Yt2tDS4MKbgIoujc?p=preview
You actually do not need the .take
and can just do this:
this.countDown = Observable.timer(0,1000)
.map(() => this.counter--)
.takeWhile(counter => counter >= 0);
https://plnkr.co/edit/L38t3LYON9DszW5N2MjA?p=preview
Upvotes: 2
Reputation: 1269
http://reactivex.io/documentation/operators/subscribe.html third argument
You may do it like this:
this.countDown = Observable
.timer(0, 1000)
.take(this.counter)
.map(() => --this.counter);
this.countDown.subscribe(() => {}, () => {}, () => (this.enableButton = true))
Or like this:
<button *ngIf="!(countDown | async)"><button>
<button *ngIf="this.counter"><button>
Upvotes: -1