Skip to content

Commit ffe85cb

Browse files
fix(NgModule): De-dupe states loaded from NgModule
Works around Angular bug: angular/angular#13652 Closes #42
1 parent a285218 commit ffe85cb

File tree

2 files changed

+16
-14
lines changed

2 files changed

+16
-14
lines changed

src/lazyLoad/lazyLoadNgModule.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
/** */
33
import { NgModuleRef, Injector, NgModuleFactory, Type, Compiler, NgModuleFactoryLoader } from "@angular/core";
44
import {
5-
Transition, LazyLoadResult, UIRouter, Resolvable, NATIVE_INJECTOR_TOKEN, isString, unnestR, inArray
5+
Transition, LazyLoadResult, UIRouter, Resolvable, NATIVE_INJECTOR_TOKEN, isString, unnestR, inArray, StateObject,
6+
uniqR
67
} from "ui-router-core";
7-
import { RootModule, UIROUTER_ROOT_MODULE, UIROUTER_MODULE_TOKEN } from "../uiRouterNgModule";
8+
import { RootModule, UIROUTER_ROOT_MODULE, UIROUTER_MODULE_TOKEN, StatesModule } from "../uiRouterNgModule";
89
import { applyModuleConfig } from "../uiRouterConfig";
910

1011
/**
@@ -143,14 +144,20 @@ export function applyNgModule(transition: Transition, ng2Module: NgModuleRef<any
143144
// Final name (without the .**)
144145
let replacementName = isFuture && isFuture[1];
145146

146-
let newRootModules: RootModule[] = multiProviderParentChildDelta(parentInjector, injector, UIROUTER_ROOT_MODULE);
147+
let newRootModules = multiProviderParentChildDelta(parentInjector, injector, UIROUTER_ROOT_MODULE)
148+
.reduce(uniqR, []) as RootModule[];
149+
let newChildModules= multiProviderParentChildDelta(parentInjector, injector, UIROUTER_MODULE_TOKEN)
150+
.reduce(uniqR, []) as StatesModule[];
151+
147152
if (newRootModules.length) {
148153
console.log(newRootModules);
149154
throw new Error('Lazy loaded modules should not contain a UIRouterModule.forRoot() module');
150155
}
151156

152-
let newChildModules: RootModule[] = multiProviderParentChildDelta(parentInjector, injector, UIROUTER_MODULE_TOKEN);
153-
newChildModules.forEach(module => applyModuleConfig(uiRouter, injector, module));
157+
let newStateObjects: StateObject[] = newChildModules
158+
.map(module => applyModuleConfig(uiRouter, injector, module))
159+
.reduce(unnestR, [])
160+
.reduce(uniqR, []);
154161

155162
let replacementState = registry.get(replacementName);
156163
if (!replacementState || replacementState === originalState) {
@@ -164,16 +171,11 @@ export function applyNgModule(transition: Transition, ng2Module: NgModuleRef<any
164171
// Supply the newly loaded states with the Injector from the lazy loaded NgModule.
165172
// If a tree of states is lazy loaded, only add the injector to the root of the lazy loaded tree.
166173
// The children will get the injector by resolve inheritance.
167-
let newStates = newChildModules.map(module => module.states)
168-
.reduce(unnestR, [])
169-
.map(state => state.$$state());
170-
171-
let newParentStates = newStates.filter(state => !inArray(newStates, state.parent));
174+
let newParentStates = newStateObjects.filter(state => !inArray(newStateObjects, state.parent));
172175

173176
// Add the Injector to the top of the lazy loaded state tree as a resolve
174177
newParentStates.forEach(state => state.resolvables.push(Resolvable.fromData(NATIVE_INJECTOR_TOKEN, injector)));
175178

176-
177179
return {};
178180
}
179181

src/uiRouterConfig.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
/** @module ng2 */ /** */
2-
import { UIRouter, isFunction } from "ui-router-core";
2+
import { UIRouter, isFunction, StateObject } from "ui-router-core";
33
import {StatesModule, RootModule} from "./uiRouterNgModule";
44
import {Injector} from "@angular/core";
55
import {isDefined} from "ui-router-core";
66

7-
export function applyModuleConfig(uiRouter: UIRouter, injector: Injector, options: StatesModule = {}) {
7+
export function applyModuleConfig(uiRouter: UIRouter, injector: Injector, options: StatesModule = {}): StateObject[] {
88
if (isFunction(options.config)) {
99
options.config(uiRouter, injector);
1010
}
1111

1212
let states = options.states || [];
13-
states.forEach(state => uiRouter.stateRegistry.register(state));
13+
return states.map(state => uiRouter.stateRegistry.register(state));
1414
}
1515

1616
export function applyRootModuleConfig(uiRouter: UIRouter, injector: Injector, config: RootModule) {

0 commit comments

Comments
 (0)