davidesp
davidesp

Reputation: 3972

routerExtensions.navigate not working well on this NativeScript app

I have a very basic NativeScript / Angular project based on the sample code on:

https://github.com/alexziskind1/nativescript-oauth2/tree/master/demo-angular

It basically allows the user to login with Google.

Just after the user introduces his credentials, the user gets redirected back to the app and it should be redirected to the route: /authenticated.

My problem is that on the file login.component.ts, when this.routerExtensions.navigate(["/authenticated"]) method is invoked, in some circumstances the user is forwarded to that route and sometimes not. I tried to investigate a bit what the circumstances are but it looks like random.

In the other hand, I have to say that I always get the access token logged on the console. So the authService is working fine but what it is not working fine is the navigation.

Also, I don't know if I have to use:

this.routerExtensions.navigate(["/authenticated"])

or

this.routerExtensions.navigate(["../authenticated"])

In the sample code from the official site there are two dots (second case) as you can see here:

https://github.com/alexziskind1/nativescript-oauth2/blob/master/demo-angular/src/app/login/login.component.ts#L23

but that doesn't seem to be the problem.

I think I'm ommitting something here.

Below you have some fragments of my code.

Any idea about how can I solve this situation?

Thanks!

app.component.html

<!-- https://docs.nativescript.org/angular/core-concepts/angular-navigation.html#page-router-outlet -->
<page-router-outlet></page-router-outlet>

app-routing.module.ts

import { NgModule } from "@angular/core";
import { NativeScriptRouterModule } from "nativescript-angular/router";
import { Routes } from "@angular/router";

import { LoginComponent } from "./screens/login/login.component";
import { AuthenticatedComponent } from "./screens/authenticated/authenticated.component";
import { ItemsComponent } from "./item/items.component";
import { ItemDetailComponent } from "./item/item-detail.component";

const routes: Routes = [
    { path: "", redirectTo: "/login", pathMatch: "full" },
    { path: "login", component: LoginComponent },
    { path: "authenticated", component: AuthenticatedComponent },
    { path: "items", component: ItemsComponent },
    { path: "item/:id", component: ItemDetailComponent }
];

@NgModule({
    imports: [NativeScriptRouterModule.forRoot(routes)],
    exports: [NativeScriptRouterModule]
})
export class AppRoutingModule { }

login.component.html

<ActionBar title="My App" class="action-bar"></ActionBar>

<StackLayout class="form">

    <Button text="Login Social Network" (tap)="onTapLogin()" class="btn btn-primary btn-active"></Button>

</StackLayout>

login.component.ts

import { Component, OnInit } from "@angular/core";
import { RouterExtensions } from "nativescript-angular";
import { ITnsOAuthTokenResult } from "nativescript-oauth2";
import { Page } from "tns-core-modules/ui/page/page";
import { AuthService } from "../../services/auth.service";

@Component({
    templateUrl: "./login.component.html",
    styleUrls: ["./login.component.scss"],
})
export class LoginComponent implements OnInit {

    constructor(private page: Page, private authService: AuthService, private routerExtensions: RouterExtensions) {
    page.actionBarHidden = true;
    }

    ngOnInit(): void {

    }

    public onTapLogin() {
        this.authService
            .tnsOauthLogin("google")
            .then((result: ITnsOAuthTokenResult) => {
                console.log("back to login component with token " + result.accessToken);
                this.routerExtensions
                    .navigate(["/authenticated"])
                    .then(() => console.log("navigated to /authenticated"))
                    .catch(err => console.log("error navigating to /authenticated: " + err));
            })
            .catch(e => console.log("Error: " + e));
    }

}

auth.service.ts

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

import {
  TnsOAuthClient,
  ITnsOAuthTokenResult
} from "nativescript-oauth2";

@Injectable()
export class AuthService {
  private client: TnsOAuthClient = null;

  constructor() { }

  public tnsOauthLogin(providerType): Promise<ITnsOAuthTokenResult> {

    this.client = new TnsOAuthClient(providerType);

    return new Promise<ITnsOAuthTokenResult>((resolve, reject) => {
      this.client.loginWithCompletion(
        (tokenResult: ITnsOAuthTokenResult, error) => {
          if (error) {
            console.error("back to main page with error: ");
            console.error(error);
            reject(error);
          } else {
            console.log("back to main page with access token: ");
            console.log(tokenResult);
            resolve(tokenResult);
          }
        }
      );
    });

  }

  public tnsOauthLogout() {
    if (this.client) {
      this.client.logout();
    }
  }
}

Upvotes: 1

Views: 4434

Answers (2)

Mamali
Mamali

Reputation: 31

I had this issue while i used Android Emulator, i updated nativescript and changed the device used in emulator, it fixed. so try update and some changes hope it works

Upvotes: 0

Tim
Tim

Reputation: 222

In your case, I think navigating direcly to authenticated would be correct

this.routerExtension.navigate('authenticated'], {
    clearHistory: true
});

and clearing the history after successful login.

You can also try this.routerExtension.navigateByUrl('/authenticated') if you prefer that.

In any case, you can quickly add some helpful tracing in your app-routing module:

NativeScriptRouterModule.forRoot(routes, {
    enableTracing: true
})

Lastly, sometimes it helps adding a timeout before navigating, like:

public onTapLogin() {
        this.authService
            .tnsOauthLogin("google")
            .then((result: ITnsOAuthTokenResult) => {
                console.log("back to login component with token " + result.accessToken);
                setTimeout( () => {
                    this.routerExtensions
                        .navigate(["/authenticated"])
                        .then(() => console.log("navigated to /authenticated"))
                        .catch(err => console.log("error navigating to /authenticated: " + err));
                }, 300);
            })
            .catch(e => console.log("Error: " + e));
    }

but that usually is only necessary for me when navigating while having an open modal.

EDIT: So, I tried your sample project and navigation after Google signing works fine for me. Since you are getting an error randomly, I guess it can only be a UI timing issue, som my last suggestion using setTimeout would be the proper workaround.

Upvotes: 1

Related Questions