Skip to content

Page.navigatedToEvent not called after async CanActivate guard #980

Open
@Burgov

Description

@Burgov

If your main route is guarded by a guard that runs async (e.g. does an Http call before completing the observable), the Page.navigatedToEvent is never called. Linked to that, the action bar shows some weird behavior in that the page title is not removed if it's overridden in the template.

In the example below, change .timer(300) to .of(true), and it will work as expected.

This only appears to happen in the initial navigation. Subsequent navigations appear to work as expected.

Route guard:

import {CanActivate} from "@angular/router";
import {Observable} from "rxjs";
export class Guard implements CanActivate {
    canActivate() {
        return Observable.timer(300).mapTo(true);
    }
}

AppModule:

import { NgModule, APP_INITIALIZER, NO_ERRORS_SCHEMA } from "@angular/core";
import { NativeScriptModule } from "nativescript-angular/nativescript.module";

import { AppComponent } from "./app.component";
import {NativeScriptRouterModule} from "nativescript-angular";
import {HomeComponent} from "./home.component";
import {Observable} from "rxjs";
import {Guard} from "./guard.service";

var pages = [
  { path: "", component: HomeComponent, canActivate: [Guard] }
]

@NgModule({
  bootstrap: [AppComponent],
  declarations: [AppComponent, HomeComponent],
  imports: [NativeScriptModule, NativeScriptRouterModule, NativeScriptRouterModule.forRoot(pages)],
  schemas: [NO_ERRORS_SCHEMA],
  providers: [Guard]
})
export class AppModule {}

AppComponent:

import {Component} from "@angular/core";

@Component({
  selector: "my-app",
  template: `
    <page-router-outlet></page-router-outlet>
  `
})
export class AppComponent {
}

HomeComponent:

import {Component, OnInit} from "@angular/core";
import {Page} from "tns-core-modules/ui/page/page";

@Component({
    template: `
    <ActionBar title="My App" class="action-bar">
        <Label text="test"></Label>
    </ActionBar>
    
    <Label text="test"></Label>
  `,
})
export class HomeComponent implements OnInit {
    constructor(private page: Page) {
    }

    ngOnInit() {
        this.page.on(Page.navigatedToEvent, () => console.log('navto'))
    }
}

I tried to circumvent it by setting initialNavigation to false in the router, loading all the necessary data for the Guard in an APP_INITIALIZER and triggering initialNavigation from there, but that seems to yield the same behavior. In that case, this is the code:

AppModule:

import {NgModule, APP_INITIALIZER, NO_ERRORS_SCHEMA, Injector} from "@angular/core";
import { NativeScriptModule } from "nativescript-angular/nativescript.module";

import { AppComponent } from "./app.component";
import {NativeScriptRouterModule} from "nativescript-angular";
import {HomeComponent} from "./home.component";
import {Observable} from "rxjs";
import {Guard} from "./guard.service";
import {Router} from "@angular/router";

var pages = [
  { path: "", component: HomeComponent, canActivate: [Guard] }
]

@NgModule({
  bootstrap: [AppComponent],
  declarations: [AppComponent, HomeComponent],
  imports: [NativeScriptModule, NativeScriptRouterModule, NativeScriptRouterModule.forRoot(pages, {initialNavigation:false})],
  schemas: [NO_ERRORS_SCHEMA],
  providers: [Guard, {
    provide: APP_INITIALIZER,
    useFactory: (injector: Injector) => () => {
      Observable.timer(300).do(() => {
        injector.get(Router).initialNavigation();
      }).toPromise();
    },
    deps: [Injector],
    multi: true
  }]
})
export class AppModule {}

Guard:

import {CanActivate} from "@angular/router";
import {Observable} from "rxjs";
export class Guard implements CanActivate {
    canActivate() {
        return Observable.of(true);
    }
}

image
This screenshot shows how the text "test"doesn't replace the app title, but is appended to it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions