Skip to content

Commit 0ad87f6

Browse files
authoredSep 26, 2019
feat(resolve): Remove RXWAIT async policy in favour of allowing user defined async policy function (#366)
BREAKING CHANGE: RXWAIT async policy has been removed, but it never worked in the first place
1 parent df263a9 commit 0ad87f6

File tree

3 files changed

+60
-35
lines changed

3 files changed

+60
-35
lines changed
 

‎src/resolve/interface.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,8 @@ export interface ResolvePolicy {
200200
}
201201

202202
export type PolicyWhen = 'LAZY' | 'EAGER';
203-
export type PolicyAsync = 'WAIT' | 'NOWAIT' | 'RXWAIT';
203+
export type PolicyAsync = 'WAIT' | 'NOWAIT' | CustomAsyncPolicy;
204+
export type CustomAsyncPolicy = <TResolveFnResult, TResolveValue>(data: TResolveFnResult) => Promise<TResolveValue>;
204205

205206
/** @internalapi */
206207
export let resolvePolicies = {

‎src/resolve/resolvable.ts

+6-20
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/** @publicapi @module resolve */ /** */
2-
import { extend, equals, inArray, identity } from '../common/common';
2+
import { extend, identity } from '../common/common';
33
import { services } from '../common/coreservices';
44
import { trace } from '../common/trace';
5-
import { ResolvePolicy, ResolvableLiteral, resolvePolicies } from './interface';
5+
import { ResolvePolicy, ResolvableLiteral, PolicyAsync } from './interface';
66

77
import { ResolveContext } from './resolveContext';
88
import { stringify } from '../common/strings';
@@ -117,26 +117,12 @@ export class Resolvable implements ResolvableLiteral {
117117
// Invokes the resolve function passing the resolved dependencies as arguments
118118
const invokeResolveFn = (resolvedDeps: any[]) => this.resolveFn.apply(null, resolvedDeps);
119119

120-
/**
121-
* For RXWAIT policy:
122-
*
123-
* Given an observable returned from a resolve function:
124-
* - enables .cache() mode (this allows multicast subscribers)
125-
* - then calls toPromise() (this triggers subscribe() and thus fetches)
126-
* - Waits for the promise, then return the cached observable (not the first emitted value).
127-
*/
128-
const waitForRx = (observable$: any) => {
129-
const cached = observable$.cache(1);
130-
return cached
131-
.take(1)
132-
.toPromise()
133-
.then(() => cached);
134-
};
135-
136120
// If the resolve policy is RXWAIT, wait for the observable to emit something. otherwise pass through.
137121
const node: PathNode = resolveContext.findNode(this);
138122
const state: StateObject = node && node.state;
139-
const maybeWaitForRx = this.getPolicy(state).async === 'RXWAIT' ? waitForRx : identity;
123+
124+
const asyncPolicy: PolicyAsync = this.getPolicy(state).async;
125+
const customAsyncPolicy = isFunction(asyncPolicy) ? asyncPolicy : identity;
140126

141127
// After the final value has been resolved, update the state of the Resolvable
142128
const applyResolvedValue = (resolvedValue: any) => {
@@ -152,7 +138,7 @@ export class Resolvable implements ResolvableLiteral {
152138
.when()
153139
.then(getResolvableDependencies)
154140
.then(invokeResolveFn)
155-
.then(maybeWaitForRx)
141+
.then(customAsyncPolicy)
156142
.then(applyResolvedValue));
157143
}
158144

‎test/resolveSpec.ts

+52-14
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import { ResolveContext, StateObject, PathNode, Resolvable, copy } from '../src/index';
1+
import { tail } from '../src/common/common';
22
import { services } from '../src/common/coreservices';
3-
import { tree2Array } from './_testUtils';
3+
import { copy, CustomAsyncPolicy, PathNode, Resolvable, ResolveContext, StateObject } from '../src/index';
44
import { UIRouter } from '../src/router';
5-
6-
import { TestingPlugin } from './_testingPlugin';
5+
import { StateRegistry } from '../src/state/stateRegistry';
76
import { StateService } from '../src/state/stateService';
87
import { TransitionService } from '../src/transition/transitionService';
9-
import { StateRegistry } from '../src/state/stateRegistry';
10-
import { tail } from '../src/common/common';
8+
9+
import { TestingPlugin } from './_testingPlugin';
10+
import { tree2Array } from './_testUtils';
1111

1212
///////////////////////////////////////////////
1313

@@ -426,6 +426,7 @@ describe('Resolvables system:', function() {
426426
const ctx = new ResolveContext(path);
427427

428428
let result;
429+
429430
function checkCounts() {
430431
expect(result).toBe('JJ2K');
431432
expect(counts['_J']).toBe(1);
@@ -561,10 +562,11 @@ describe('Resolvables system:', function() {
561562

562563
describe('NOWAIT Resolve Policy', () => {
563564
it('should allow a transition to complete before the resolve is settled', async done => {
564-
let resolve,
565-
resolvePromise = new Promise(_resolve => {
566-
resolve = _resolve;
567-
});
565+
let resolve;
566+
567+
const resolvePromise = new Promise(_resolve => {
568+
resolve = _resolve;
569+
});
568570

569571
$registry.register({
570572
name: 'nowait',
@@ -599,10 +601,11 @@ describe('Resolvables system:', function() {
599601
});
600602

601603
it('should wait for WAIT resolves and not wait for NOWAIT resolves', async done => {
602-
let promiseResolveFn,
603-
resolvePromise = new Promise(resolve => {
604-
promiseResolveFn = resolve;
605-
});
604+
let promiseResolveFn;
605+
606+
const resolvePromise = new Promise(resolve => {
607+
promiseResolveFn = resolve;
608+
});
606609

607610
$registry.register({
608611
name: 'nowait',
@@ -635,4 +638,39 @@ describe('Resolvables system:', function() {
635638
$state.go('nowait');
636639
});
637640
});
641+
642+
describe('custom Resolve Policy', () => {
643+
let customResolvePolicy: CustomAsyncPolicy;
644+
645+
it('should wait for the promise to resolve before finishing the transition', async done => {
646+
let resolve: (value: string) => void;
647+
648+
const resolvePromise: Promise<string> = new Promise(_resolve => {
649+
resolve = _resolve;
650+
});
651+
652+
customResolvePolicy = jasmine.createSpy('customResolvePolicy');
653+
654+
(customResolvePolicy as jasmine.Spy).and.callFake((data: { useMe: Promise<string> }) => {
655+
return data.useMe;
656+
});
657+
658+
resolve('myAwaitedValue');
659+
660+
$registry.register({
661+
name: 'customPolicy',
662+
resolve: {
663+
customWait: () => ({ useMe: resolvePromise }),
664+
},
665+
resolvePolicy: { async: customResolvePolicy },
666+
});
667+
668+
$transitions.onSuccess({}, trans => {
669+
expect(customResolvePolicy).toHaveBeenCalledWith({ useMe: resolvePromise });
670+
expect(trans.injector().get('customWait')).toBe('myAwaitedValue');
671+
});
672+
673+
$state.go('customPolicy').then(done);
674+
});
675+
});
638676
});

0 commit comments

Comments
 (0)
Please sign in to comment.