1

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();
    }
  }
}
davidesp
  • 3,743
  • 10
  • 39
  • 77
  • Just a sanity check, you aren't using an interceptor to handle your requests by any chance? If you do, that might be stopping the navigation action. – JillevdW Jul 09 '19 at 10:54
  • did you ever solve this issue? I'm having the exact same issue currently – Ben Pap Oct 15 '19 at 23:35

2 Answers2

1

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.

Tim
  • 212
  • 1
  • 7
  • Which part? Removing the '/', using navigateByUrl, using a timeout, or enabling trace to get details about the issue? – Tim Jun 26 '19 at 13:40
  • I tried all of that with no success.Here you have more detailed info about the issue: https://github.com/napolev/evalproject.com-debug – davidesp Jun 28 '19 at 05:07
  • So you activated router tracing and did not get anything extra in the console? – Tim Jun 29 '19 at 14:42
0

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

Mamali
  • 31
  • 5