Skip to content

Instantly share code, notes, and snippets.

@lydemann
Created July 4, 2018 15:03
Show Gist options
  • Save lydemann/a83a5e29e8c4d783e94444ebdb552a10 to your computer and use it in GitHub Desktop.
Save lydemann/a83a5e29e8c4d783e94444ebdb552a10 to your computer and use it in GitHub Desktop.
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