问题
I am working in my Ionic 4 app and I am working in my login/register system. I have defined the route with the id and when the user is not login and try to visit that route, it will redirect to login page and when the user is login then he can visit that route but the problem is that when the user is trying to visit that route with the id, it is showing the error.
This is my tabs.router.module.ts:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { TabsPage } from './tabs.page';
import { AuthenticationGuard } from '../guards/authentication.guard';
const routes: Routes = [
{
path: 'tabs',
component: TabsPage,
children: [
{
path: 'tab1',
children: [
{
path: '',
loadChildren: '../tab1/tab1.module#Tab1PageModule'
}
]
},
{
path: 'tab2/:id',
canActivate: [AuthenticationGuard],
children: [
{
path: '',
loadChildren: '../tab2/tab2.module#Tab2PageModule'
}
]
},
{
path: 'tab4',
children: [
{
path: '',
loadChildren: '../login/login.module#LoginPageModule'
}
]
},
{
path: 'tab3',
children: [
{
path: '',
loadChildren: '../tab3/tab3.module#Tab3PageModule'
}
]
},
{
path: '',
redirectTo: '/tabs/tab1',
pathMatch: 'full'
}
]
},
{
path: '',
redirectTo: '/tabs/tab1',
pathMatch: 'full'
}
];
@NgModule({
imports: [
RouterModule.forChild(routes)
],
exports: [RouterModule]
})
export class TabsPageRoutingModule {}
In this tab2 is with id.
This is my authentication.guard.ts:
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { Storage } from '@ionic/storage';
import { Router } from '@angular/router';
import { AlertController } from '@ionic/angular';
@Injectable({
providedIn: 'root'
})
export class AuthenticationGuard implements CanActivate {
constructor(private router: Router, private storage: Storage, public alertController: AlertController) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
let isLoggedIn = false;
this.storage.get('ID').then((val) => {
if (val) {
isLoggedIn = true;
return true;
} else {
this.presentAlertConfirm();
return false;
}
});
return true;
}
async presentAlertConfirm() {
const alert = await this.alertController.create({
message: 'Please Login To Participate In The Challenge',
buttons: [
{
text: 'Cancel',
role: 'cancel',
cssClass: 'secondary',
handler: () => {
this.router.navigate(['/tabs/tab4']);
}
}]
});
await alert.present();
}
}
In the guard, when the user is not login, it will redirect to the login page.
But the problem is when I try to visit the tab2 page, it is showing the error.
Any help is much appreciated.
回答1:
You should move this.router.navigate(['/tabs/tab4']); to AuthGuard if you want to redirect after error. Currently you navigate to /tabs/tab4 in Cancel button click handle.
@Injectable()
export class AuthGuard implements CanActivate {
constructor(
private _router: Router,
) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Promise<boolean> | boolean {
return new Promise((resolve, reject) => {
return this.storage.get('ID').then((val) => {
if (val) {
isLoggedIn = true;
resolve(true)
} else {
// Place your redirect here:
this.router.navigate(['/tabs/tab4']);
this.presentAlertConfirm();
resolve(false);
}
})
}
async presentAlertConfirm() {
const alert = await this.alertController.create({
message: 'Please Login To Participate In The Challenge',
buttons: [
{
text: 'Cancel',
role: 'cancel',
cssClass: 'secondary',
handler: () => {
resolve(true)
}
}]
});
await alert.present();
}
}
回答2:
Try resolving the Promise on your auth guard. My guess is that right now you're choosing to return a boolean, but you're using a storage service that requires a promise, so you're not waiting for the promise chain to finish executing.
@Injectable()
export class AuthGuard implements CanActivate {
constructor(
private _router: Router,
) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Promise<boolean> | boolean {
return new Promise((resolve, reject) => {
return this.storage.get('ID').then((val) => {
if (val) {
isLoggedIn = true;
resolve(true)
} else {
this.presentAlertConfirm();
}
})
}
async presentAlertConfirm() {
const alert = await this.alertController.create({
message: 'Please Login To Participate In The Challenge',
buttons: [
{
text: 'Cancel',
role: 'cancel',
cssClass: 'secondary',
handler: () => {
resolve(true)
this.router.navigate(['/tabs/tab4']);
}
}]
});
await alert.present();
}
}
来源:https://stackoverflow.com/questions/54996059/how-to-redirect-the-user-from-the-route-defined-with-id-when-the-user-is-not-log