Skip to content

Commit ccc75ee

Browse files
ADjenkovADjenkov
ADjenkov
authored and
ADjenkov
committed
fix(location-strategy): crash on going back with router-outlet after closing modal
1 parent 4715f5e commit ccc75ee

File tree

3 files changed

+35
-28
lines changed

3 files changed

+35
-28
lines changed

nativescript-angular/directives/dialogs.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,7 @@ export class ModalDialogService {
8787
frame = (parentView.page && parentView.page.frame) || topmost();
8888
}
8989

90-
if (frame) {
91-
this.location._beginModalNavigation(frame);
92-
}
90+
this.location._beginModalNavigation(frame);
9391

9492
return new Promise((resolve, reject) => {
9593
setTimeout(() => {

nativescript-angular/router/ns-location-strategy.ts

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -275,9 +275,13 @@ export class NSLocationStrategy extends LocationStrategy {
275275

276276
if (!outlet) {
277277
const topmostFrame = this.frameService.getFrame();
278-
this.currentOutlet = this.getOutletByFrame(topmostFrame);
278+
this.currentOutlet = this.getOutletByFrame(topmostFrame) || this.currentOutlet;
279+
}
280+
281+
const frameToBack: Frame = this.currentOutlet.getFrameToBack();
282+
if (frameToBack) {
283+
frameToBack.goBack();
279284
}
280-
this.currentOutlet.getFrameToBack().goBack();
281285
} else {
282286
// Nested navigation - just pop the state
283287
if (isLogEnabled()) {
@@ -385,10 +389,11 @@ export class NSLocationStrategy extends LocationStrategy {
385389
routerLog("NSLocationStrategy._beginModalNavigation()");
386390
}
387391

388-
this.currentOutlet = this.getOutletByFrame(frame);
392+
this.currentOutlet = this.getOutletByFrame(frame) || this.currentOutlet;
389393

390394
// It is possible to have frame, but not corresponding Outlet, if
391-
// showing modal dialog on app.component.ts ngOnInit() e.g.
395+
// showing modal dialog on app.component.ts ngOnInit() e.g. In that case
396+
// the modal is treated as none modal navigation.
392397
if (this.currentOutlet) {
393398
this.currentOutlet.showingModal = true;
394399
this._modalNavigationDepth++;
@@ -400,15 +405,18 @@ export class NSLocationStrategy extends LocationStrategy {
400405
routerLog("NSLocationStrategy.closeModalNavigation()");
401406
}
402407

403-
if (this._modalNavigationDepth > 0) {
408+
const isShowingModal = this._modalNavigationDepth > 0;
409+
410+
if (isShowingModal) {
404411
this._modalNavigationDepth--;
405412
}
406413

407414
// currentOutlet should be the one that corresponds to the topmost() frame
408415
const topmostOutlet = this.getOutletByFrame(this.frameService.getFrame());
409-
this.currentOutlet = this.findOutletByModal(this._modalNavigationDepth, true) || topmostOutlet;
416+
const outlet = this.findOutletByModal(this._modalNavigationDepth, isShowingModal) || topmostOutlet;
410417

411-
if (this.currentOutlet) {
418+
if (outlet) {
419+
this.currentOutlet = outlet;
412420
this.currentOutlet.showingModal = false;
413421
this.callPopState(this.currentOutlet.peekState(), false);
414422
}
@@ -481,7 +489,8 @@ export class NSLocationStrategy extends LocationStrategy {
481489
this.callPopState(null, true, currentOutlet);
482490
}
483491

484-
if (!currentOutlet.isNSEmptyOutlet) {
492+
// Skip frames filtering since currentOutlet is <router-outlet> when no frames available.
493+
if (currentOutlet.frames.length && !currentOutlet.isNSEmptyOutlet) {
485494
currentOutlet.frames = currentOutlet.frames.filter(currentFrame => currentFrame !== frame);
486495
return currentOutlet.frames.length;
487496
}
@@ -554,26 +563,33 @@ export class NSLocationStrategy extends LocationStrategy {
554563
return pathToOutlet || lastPath;
555564
}
556565

557-
findOutletByModal(modalNavigation: number, isShowingModal?: boolean): Outlet {
558-
return this.outlets.find((outlet) => {
559-
let isEqual = outlet.modalNavigationDepth === modalNavigation;
560-
return isShowingModal ? isEqual && outlet.showingModal : isEqual;
561-
});
562-
}
563-
564566
findOutlet(outletKey: string, activatedRouteSnapshot?: ActivatedRouteSnapshot): Outlet {
565-
let outlet: Outlet = this.outlets.find((currentOutlet) => currentOutlet.outletKeys.indexOf(outletKey) > -1);
567+
const that = this;
568+
let outlet: Outlet = this.outlets.find((currentOutlet) => {
569+
let equalModalDepth = currentOutlet.modalNavigationDepth === that._modalNavigationDepth;
570+
return currentOutlet.outletKeys.indexOf(outletKey) > -1 && equalModalDepth;
571+
});
566572

567573
// No Outlet with the given outletKey could happen when using nested unnamed p-r-o
568574
// primary -> primary -> prymary
569575
if (!outlet && activatedRouteSnapshot) {
570576
const pathByOutlets = this.getPathByOutlets(activatedRouteSnapshot);
571-
outlet = this.outlets.find((currentOutlet) => currentOutlet.pathByOutlets === pathByOutlets);
577+
outlet = this.outlets.find((currentOutlet) => {
578+
let equalModalDepth = currentOutlet.modalNavigationDepth === that._modalNavigationDepth;
579+
return currentOutlet.pathByOutlets === pathByOutlets && equalModalDepth;
580+
});
572581
}
573582

574583
return outlet;
575584
}
576585

586+
private findOutletByModal(modalNavigation: number, isShowingModal?: boolean): Outlet {
587+
return this.outlets.find((outlet) => {
588+
let equalModalDepth = outlet.modalNavigationDepth === modalNavigation;
589+
return isShowingModal ? equalModalDepth && outlet.showingModal : equalModalDepth;
590+
});
591+
}
592+
577593
private getOutletByFrame(frame: Frame): Outlet {
578594
let outlet;
579595

nativescript-angular/router/page-router-outlet.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -422,15 +422,8 @@ export class PageRouterOutlet implements OnDestroy { // tslint:disable-line:dire
422422

423423
private getOutlet(activatedRouteSnapshot: ActivatedRouteSnapshot): Outlet {
424424
const topActivatedRoute = findTopActivatedRouteNodeForOutlet(activatedRouteSnapshot);
425-
const modalNavigation = this.locationStrategy._modalNavigationDepth;
426425
const outletKey = this.locationStrategy.getRouteFullPath(topActivatedRoute);
427-
let outlet;
428-
429-
if (modalNavigation > 0) { // Modal with 'primary' p-r-o
430-
outlet = this.locationStrategy.findOutletByModal(modalNavigation);
431-
} else {
432-
outlet = this.locationStrategy.findOutlet(outletKey, topActivatedRoute);
433-
}
426+
let outlet = this.locationStrategy.findOutlet(outletKey, topActivatedRoute);
434427

435428
// Named lazy loaded outlet.
436429
if (!outlet && this.isEmptyOutlet) {

0 commit comments

Comments
 (0)