I have the problem with the progress bar. I am using for it ng-bootstrap module.
I have multiple option in dropdown, and I would like below behavior: - I can start/stop progress bar for each option from dropdown separatly, - When I change option to another option, and come back -> counting will be in the background.
Below solution was working perfectly. But, like in IT, sth was changed and I did not see the bug.
Service file:
@Injectable()
export class TimerService {
constructor(private httpClient: HttpClient) {
}
private timer = [];
private timerStarted: boolean [] = [false];
private stopTimer$: Subject<any> [] = [];
startTimer(duration: number, indexDropdown: number) {
this.stopTimer$[indexDropdown] = new Subject();
this.timerStarted[indexDropdown] = false;
this.timer[indexDropdown] = interval(duration).pipe(take(1000), takeUntil(this.stopTimer$[indexDropdown]), share());
this.timer[indexDropdown].pipe(
tap(() => this.timerStarted[indexDropdown] = true),
finalize(() => this.timerStarted[indexDropdown] = false)
).subscribe();
}
getTimer(indexDropdown: number) {
return this.timer[indexDropdown];
}
getTimerStarted(indexDropdown: number) {
return this.timerStarted[indexDropdown];
}
stopTimer(indexDropdown: number) {
this.stopTimer$[indexDropdown].next();
}
}
And component file:
export class TimerComponent implements OnInit, OnDestroy, OnChanges {
@Input() optionDropdownArray: string[];
isLoading: boolean;
progress: number [] = [0];
private destroy$: Subject<boolean>[] = [];
private loadingIndexSub: Subscription;
selectedIndex = 0;
timerObserver$ = [];
constructor(
private timerService: timerService,
private timerStore$: Store<TimerStatus>,
private indexService: TimerService,
private config: NgbProgressbarConfig) {
config.max = 1000;
config.striped = false;
config.animated = false;
config.type = 'success';
config.height = '3.5em';
}
ngOnChanges(): void {
this.loadingIndexSub = this.indexService.gettingIndexSelected.subscribe(getIndex => {
this.selectedIndex = getIndex;
this.isLoading = false;
this.checkProgressSubscriptions();
if (this.timerService.getTimerStarted(getIndex)) {
this.destroy$[this.selectedIndex] = new Subject<false>();
this.progress[getIndex] = this.timerService.getTimer(getIndex).pipe(take(1)).subscribe();
this.checkProgressSubscriptions();
this.subscribeToStartedTimer(getIndex);
this.isLoading = true;
}
});
}
ngOnInit() {
this.loadingIndexSub = this.indexService.gettingIndexSelected.subscribe(getIndex => {
this.selectedIndex = getIndex;
});
}
private startProcessing() {
this.destroy$[this.selectedIndex] = new Subject<boolean>();
this.isLoading = true;
this.progress[this.selectedIndex] = 0;
this.timerStore$
.select(selectDurationActiveWorkStep, {timerSelectorProps: this.selectedIndex}).subscribe(timeArray => {
this.timerService.startTimer(timeArray.activeTaskDuration, this.selectedIndex);
this.subscribeToStartedTimer(this.selectedIndex);
});
}
private stopProcessing() {
this.isLoading = false;
if (this.destroy$[this.selectedIndex] != undefined) {
this.destroy$[this.selectedIndex].next(true);
}
this.timerService.stopTimer(this.selectedIndex);
}
private subscribeToStartedTimer(dropdownIndexId: number) {
this.timerObserver$[dropdownIndexId] = this.timerService.getTimer(dropdownIndexId).pipe(
takeUntil(this.destroy$[dropdownIndexId])
).subscribe((val => {
this.progress[dropdownIndexId] = val + 1;
}));
}
private checkProgressSubscriptions() {
for (let i = 0; i < this.optionDropdownArray.length; i++) {
if (this.timerObserver$[i]) {
this.timerObserver$[i].unsubscribe();
}
}
}
ngOnDestroy() {
if (this.destroy$[this.selectedIndex] != undefined) {
this.destroy$[this.selectedIndex].next(true);
}
}
}
from Angular, progress bar - asynchronous starting/stoping
No comments:
Post a Comment