-
-
Save lydemann/a83a5e29e8c4d783e94444ebdb552a10 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { select } from '@angular-redux/store'; | |
import { Injectable } from '@angular/core'; | |
import { QueryParamService } from '@app/core/query-param/query-param.service'; | |
import { isEqual } from 'lodash'; | |
import { Subscription } from 'rxjs'; | |
import { Observable } from 'rxjs/Observable'; | |
import { distinctUntilChanged, filter, map, skip, withLatestFrom } from 'rxjs/operators'; | |
export declare type syncedQueryParams = SyncedQueryParam[]; | |
export declare interface SyncedQueryParam { | |
selectorToUpdateQueryParam$: Observable<any>; // Subscripting to this state property and update query param | |
actionTriggeredOnQueryParamChange: (payload: any) => any; // Subscripting to query param key and dispatch action on every queryParamKey update | |
queryKey: string; // The query param key | |
} | |
@Injectable() | |
export class ReduxQuerySyncService { | |
private subscriptions: Subscription[] = []; | |
private syncedQueryParams: syncedQueryParams = [ | |
]; | |
constructor( | |
private queryParamService: QueryParamService, | |
) {} | |
public startSyncQueryParams(syncedParams: syncedQueryParams = this.syncedQueryParams) { | |
syncedParams.forEach((queryParamElm) => { | |
this.subscriptions.push( | |
this.subscribeToQueryAndDispatch(queryParamElm), | |
this.subscribeToStateAndUpdateQuery(queryParamElm) | |
); | |
}); | |
} | |
public stopSyncQueryParams() { | |
this.subscriptions.forEach((sub) => sub.unsubscribe()); | |
} | |
private subscribeToQueryAndDispatch(syncedQueryParamObj: SyncedQueryParam) { | |
return this.queryParamService | |
.getQueryParam(syncedQueryParamObj.queryKey) | |
.pipe( | |
distinctUntilChanged((prev, cur) => { | |
return isEqual(prev, cur); | |
}) | |
) | |
.subscribe((payload) => { | |
syncedQueryParamObj.actionTriggeredOnQueryParamChange(payload); | |
}); | |
} | |
private subscribeToStateAndUpdateQuery(syncedQueryParamObj: SyncedQueryParam) { | |
return syncedQueryParamObj.selectorToUpdateQueryParam$.subscribe((value) => { | |
if (value) { | |
this.queryParamService.setQueryParam(syncedQueryParamObj.queryKey, value); | |
} else { | |
this.queryParamService.removeQueryParam(syncedQueryParamObj.queryKey); | |
} | |
}); | |
} | |
public addSyncedQueryParam(syncedParam: SyncedQueryParam) { | |
this.stopSyncQueryParams(); | |
const exists = this.syncedQueryParams.some((param) => param.queryKey === syncedParam.queryKey); | |
if (!exists) { | |
this.syncedQueryParams.push(syncedParam); | |
} | |
this.startSyncQueryParams(this.syncedQueryParams); | |
} | |
public unsyncQueryParam(queryParamKey: string) { | |
this.stopSyncQueryParams(); | |
const syncedQueryParamIdxToRemove = this.syncedQueryParams.findIndex( | |
(param) => param.queryKey === queryParamKey | |
); | |
this.syncedQueryParams = this.syncedQueryParams.splice(syncedQueryParamIdxToRemove, 1); | |
this.startSyncQueryParams(this.syncedQueryParams); | |
this.queryParamService.removeQueryParam(queryParamKey); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment