Wednesday 15 January 2020

Angular, progress bar - asynchronous starting/stoping

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