Browse Source

convert navigation events to router events service

pull/7537/head
Arman Ozak 6 years ago
parent
commit
1399778913
  1. 2
      npm/ng-packs/packages/core/src/lib/services/index.ts
  2. 36
      npm/ng-packs/packages/core/src/lib/services/navigation-events.service.ts
  3. 60
      npm/ng-packs/packages/core/src/lib/services/router-events.service.ts
  4. 75
      npm/ng-packs/packages/core/src/lib/tests/navigation-events.service.spec.ts
  5. 111
      npm/ng-packs/packages/core/src/lib/tests/router-events.service.spec.ts

2
npm/ng-packs/packages/core/src/lib/services/index.ts

@ -9,13 +9,13 @@ export * from './lazy-load.service';
export * from './list.service';
export * from './localization.service';
export * from './multi-tenancy.service';
export * from './navigation-events.service';
export * from './permission.service';
export * from './profile-state.service';
export * from './profile.service';
export * from './replaceable-components.service';
export * from './resource-wait.service';
export * from './rest.service';
export * from './router-events.service';
export * from './router-wait.service';
export * from './routes.service';
export * from './session-state.service';

36
npm/ng-packs/packages/core/src/lib/services/navigation-events.service.ts

@ -1,36 +0,0 @@
import { Injectable, Type } from '@angular/core';
import {
NavigationCancel,
NavigationEnd,
NavigationError,
NavigationStart,
Router,
RouterEvent,
} from '@angular/router';
import { filter } from 'rxjs/operators';
export type NavigationEventType = 'Cancel' | 'End' | 'Error' | 'Start';
@Injectable({ providedIn: 'root' })
export class NavigationEvents {
private eventTypes = new Map<NavigationEventType, Type<RouterEvent>>([
['Cancel', NavigationCancel],
['End', NavigationEnd],
['Error', NavigationError],
['Start', NavigationStart],
]);
constructor(private router: Router) {}
getOneOf(...eventTypes: NavigationEventType[]) {
return this.router.events.pipe(
filter((event: RouterEvent) =>
eventTypes.some(type => event instanceof this.eventTypes.get(type)),
),
);
}
getAny() {
return this.getOneOf(...this.eventTypes.keys());
}
}

60
npm/ng-packs/packages/core/src/lib/services/router-events.service.ts

@ -0,0 +1,60 @@
import { Injectable, Type } from '@angular/core';
import {
NavigationCancel,
NavigationEnd,
NavigationError,
NavigationStart,
Router,
RouterEvent,
} from '@angular/router';
import { filter } from 'rxjs/operators';
export const NavigationEvent = {
Cancel: NavigationCancel,
End: NavigationEnd,
Error: NavigationError,
Start: NavigationStart,
};
@Injectable({ providedIn: 'root' })
export class RouterEvents {
constructor(private router: Router) {}
getEvents<T extends RouterEventConstructors>(...eventTypes: T) {
type FilteredRouterEvent = T extends Type<infer Ctor>[] ? Ctor : never;
const filterRouterEvents = (event: RouterEvent): event is FilteredRouterEvent =>
eventTypes.some(type => event instanceof type);
return this.router.events.pipe(filter(filterRouterEvents));
}
getNavigationEvents<T extends NavigationEventKeys>(...navigationEventKeys: T) {
type FilteredNavigationEvent = T extends (infer Key)[]
? Key extends NavigationEventKey
? InstanceType<NavigationEventType[Key]>
: never
: never;
const filterNavigationEvents = (event: RouterEvent): event is FilteredNavigationEvent =>
navigationEventKeys.some(key => event instanceof NavigationEvent[key]);
return this.router.events.pipe(filter(filterNavigationEvents));
}
getAnyEvent() {
return this.router.events;
}
getAnyNavigationEvent() {
const keys = Object.keys(NavigationEvent) as NavigationEventKeys;
return this.getNavigationEvents(...keys);
}
}
type RouterEventConstructors = [Type<RouterEvent>, ...Type<RouterEvent>[]];
type NavigationEventKeys = [NavigationEventKey, ...NavigationEventKey[]];
export type NavigationEventType = typeof NavigationEvent;
export type NavigationEventKey = keyof NavigationEventType;

75
npm/ng-packs/packages/core/src/lib/tests/navigation-events.service.spec.ts

@ -1,75 +0,0 @@
import {
NavigationCancel,
NavigationEnd,
NavigationError,
NavigationStart,
Router,
RouterEvent,
} from '@angular/router';
import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest';
import { Subject } from 'rxjs';
import { take } from 'rxjs/operators';
import { NavigationEvents } from '../services/navigation-events.service';
describe('NavigationEvents', () => {
let spectator: SpectatorService<NavigationEvents>;
let service: NavigationEvents;
const events = new Subject<RouterEvent>();
const createService = createServiceFactory({
service: NavigationEvents,
providers: [
{
provide: Router,
useValue: { events },
},
],
});
beforeEach(() => {
spectator = createService();
service = spectator.service;
});
describe('getOneOf', () => {
test.each`
filtered | expected
${['Start', 'Cancel']} | ${[0, 3]}
${['Error', 'Cancel']} | ${[0, 1]}
${['Start', 'End']} | ${[2, 3]}
${['Error', 'End']} | ${[1, 2]}
`('should return a stream of given navigation events', ({ filtered, expected }) => {
const stream = service.getOneOf(...filtered);
const collected: number[] = [];
stream.pipe(take(2)).subscribe(event => collected.push(event.id));
events.next(new NavigationCancel(0, null, null));
events.next(new NavigationError(1, null, null));
events.next(new NavigationEnd(2, null, null));
events.next(new NavigationStart(3, null, null));
expect(collected).toEqual(expected);
});
});
describe('getAny', () => {
it('should return a stream of any navigation event', () => {
const stream = service.getAny();
const collected: number[] = [];
stream.pipe(take(4)).subscribe(event => collected.push(event.id));
events.next(new RouterEvent(0, null));
events.next(new NavigationStart(1, null, null));
events.next(new RouterEvent(2, null));
events.next(new RouterEvent(3, null));
events.next(new NavigationError(4, null, null));
events.next(new NavigationEnd(5, null, null));
events.next(new RouterEvent(6, null));
events.next(new NavigationCancel(7, null, null));
expect(collected).toEqual([1, 4, 5, 7]);
});
});
});

111
npm/ng-packs/packages/core/src/lib/tests/router-events.service.spec.ts

@ -0,0 +1,111 @@
import {
NavigationCancel,
NavigationEnd,
NavigationError,
NavigationStart,
ResolveEnd,
ResolveStart,
Router,
RouterEvent,
} from '@angular/router';
import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest';
import { Subject } from 'rxjs';
import { take } from 'rxjs/operators';
import { NavigationEventKey, RouterEvents } from '../services/router-events.service';
describe('RouterEvents', () => {
let spectator: SpectatorService<RouterEvents>;
let service: RouterEvents;
const events = new Subject<RouterEvent>();
const emitRouterEvents = () => {
events.next(new RouterEvent(0, null));
events.next(new NavigationStart(1, null, null));
events.next(new ResolveStart(2, null, null, null));
events.next(new RouterEvent(3, null));
events.next(new NavigationError(4, null, null));
events.next(new NavigationEnd(5, null, null));
events.next(new ResolveEnd(6, null, null, null));
events.next(new NavigationCancel(7, null, null));
};
const createService = createServiceFactory({
service: RouterEvents,
providers: [
{
provide: Router,
useValue: { events },
},
],
});
beforeEach(() => {
spectator = createService();
service = spectator.service;
});
describe('getNavigationEvents', () => {
test.each`
filtered | expected
${['Start', 'Cancel']} | ${[1, 7]}
${['Error', 'Cancel']} | ${[4, 7]}
${['Start', 'End']} | ${[1, 5]}
${['Error', 'End']} | ${[4, 5]}
`(
'should return a stream of given navigation events',
({ filtered, expected }: NavigationEventTest) => {
const stream = service.getNavigationEvents(...filtered);
const collected: number[] = [];
stream.pipe(take(2)).subscribe(event => collected.push(event.id));
emitRouterEvents();
expect(collected).toEqual(expected);
},
);
});
describe('getAnyNavigationEvent', () => {
it('should return a stream of any navigation event', () => {
const stream = service.getAnyNavigationEvent();
const collected: number[] = [];
stream.pipe(take(4)).subscribe(event => collected.push(event.id));
emitRouterEvents();
expect(collected).toEqual([1, 4, 5, 7]);
});
});
describe('getEvents', () => {
it('should return a stream of given router events', () => {
const stream = service.getEvents(ResolveEnd, ResolveStart);
const collected: number[] = [];
stream.pipe(take(2)).subscribe(event => collected.push(event.id));
emitRouterEvents();
expect(collected).toEqual([2, 6]);
});
});
describe('getAnyEvent', () => {
it('should return a stream of any router event', () => {
const stream = service.getAnyEvent();
const collected: number[] = [];
stream.pipe(take(8)).subscribe((event: RouterEvent) => collected.push(event.id));
emitRouterEvents();
expect(collected).toEqual([0, 1, 2, 3, 4, 5, 6, 7]);
});
});
});
type NavigationEventTest = {
filtered: [NavigationEventKey, ...NavigationEventKey[]];
expected: number[];
};
Loading…
Cancel
Save