import { HttpClient, HttpResponse } from '@angular/common/http';
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { fromEvent, merge, Observable, of } from 'rxjs';
import { map, share, startWith, switchMap, withLatestFrom } from 'rxjs/operators';
@Component({
selector: 'strum-test-pagination',
templateUrl: './test-pagination.component.html',
styleUrls: ['./test-pagination.component.scss']
})
export class TestPaginationComponent implements OnInit {
@ViewChild('nextBtn') nextBtnRef: ElementRef;
@ViewChild('backBtn') backBtnRef: ElementRef;
state$: Observable<PaginationState>;
httpCall$ = this.http.get('', { observe: 'response' }).pipe(share()) //Assume that server response contains a header 'totalCount'
constructor(private http: HttpClient) { }
ngOnInit(): void {
const getHttpCall = (state: PaginationState) => this.http.get<string[]>(`serviceEndpoint?skip=${state.skip}&take=${state.pageSize}`, { observe: 'response' }).pipe(share())
const getStateFromResponse = (response: HttpResponse<string[]>, state: PaginationState): PaginationState => ({
...state,
total: +response.headers.get('totalCount'),
data: response.body
})
const next$ = fromEvent(this.nextBtnRef.nativeElement, 'click').pipe(
withLatestFrom(this.state$),
map(([_, state]) => ({ ...state, skip: state.skip + state.pageSize }))
)
const prev$ = fromEvent(this.backBtnRef.nativeElement, 'click').pipe(
withLatestFrom(this.state$),
map(([_, state]) => ({ ...state, skip: state.skip - state.pageSize }))
)
this.state$ = merge(next$, prev$).pipe(
startWith({ skip: 0, total: 0, pageSize: 25, data: [] }),
switchMap(state => getHttpCall(state).pipe(map(res => getStateFromResponse(res, state)))),
share()
)
}
}
interface PaginationState {
skip: number,
total: number,
pageSize: number,
data: string[]
}