Reputation: 11
I am trying to protect one of my routes in this Angular app I have made. I think I have implemented it correctly however, am running into this error when the negative scenario is invoked: ERROR Error: Uncaught (in promise): [object Boolean]
. What I also can't understand is that it seems to work when I meet the conditions to allow the route?! Code below:
Routing Module
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { RecipesComponent } from './recipes/recipes.component';
import { ShoppingListComponent } from './shopping-list/shopping-list.component';
import { RecipeDetailComponent } from './recipes/recipe-detail/recipe-detail.component';
import { RecipeStartComponent } from './recipes/recipe-start/recipe-start.component';
import { RecipeEditComponent } from './recipes/recipe-edit/recipe-edit.component';
import { AuthGuard } from './shared/guard.service';
const appRoutes: Routes = [
{path: '', redirectTo: '/recipes',pathMatch: 'full' },
{path: 'recipes', component: RecipesComponent,
children:[
{path: '', component: RecipeStartComponent},
{path: 'new', component:RecipeEditComponent},
{path: ':id', component: RecipeDetailComponent, canActivate: [AuthGuard]},
{path: ':id/edit', component:RecipeEditComponent}
]},
{path: 'shopping-list', component: ShoppingListComponent}
]
@NgModule({
imports: [
RouterModule.forRoot(appRoutes)
],
exports: [RouterModule]
})
export class AppRoutingModule {
}
Auth Service
import { OnDestroy, Injectable } from "@angular/core";
import { RecipeService } from "../recipes/recipe.service";
@Injectable()
export class AuthService implements OnDestroy {
constructor(private recipeService: RecipeService){
console.log(this.loadedReceipe)
}
private loadedReceipe: boolean = false
setRecipe(){
this.loadedReceipe = true;
console.log(`setting the recipe to true`)
}
isAuthenticated() {
const promise = new Promise(
(resolve, reject) => {
if(this.recipeService.getRecipes().length > 0){
console.log(`resolving`)
resolve (true)
}else{
console.log(`rejecting`)
reject(false)
}
}
);
return promise;
}
ngOnDestroy()
{
console.log(this.loadedReceipe);
}
}
Guard Service
import {
CanActivate,
CanActivateChild,
ActivatedRouteSnapshot,
RouterStateSnapshot,
Router
} from '@angular/router';
import { Injectable } from '@angular/core';
import {Observable} from 'rxjs'
import { AuthService } from './auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate, CanActivateChild {
constructor(private authService: AuthService, private router: Router) {}
canActivate(route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean{
return this.authService.isAuthenticated()
.then(
(authenticated: boolean) => {
if (authenticated) {
console.log(`got here1`)
return true;
} else {
console.log(`got here2`)
this.router.navigate(['/recipes']);
}
}
)
}
canActivateChild(route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
return this.canActivate(route, state);
}
}
Does anyone know what is going on here? Any help would be much appreciated!
Upvotes: 1
Views: 5939
Reputation: 412
Sometime you get error due to catch try to open it in incognito mode
Upvotes: 0
Reputation: 183
I have tried it out from my end was getting the same error and this is how i fixed it.
As you can see in the screen shot I am not allowing the user to access the server route.
My Initial Auth service with isAuthenticated() method is as following
In order to prevent this error we need to catch it as shown below.
Now i am not getting any error.
Upvotes: 1
Reputation: 410
Faced the exact same error but for a different scenario than the OP's.
I was rejecting a promise for an await statement and looked like error couldn't find a place to get caught after rejection and threw "Error: Uncaught (in promise): [object Boolean]".
Placing my await statement under try catch block fixed the error.
Adding my code below in case someone encounters same issue:
DataService.ts
serviceCall(): Promise<SomeEntity | HttpErrorResponse> {
return new Promise((resolve, reject) => {
myService.doSomeWork()
.then(data => {
resolve(data);
})
.catch(error => {
reject(error)
})
})
}
Component.ts
try {
await DataService.serviceCall();
} catch (error) {
// error from the rejected promise should get caught here
console.log(error)
}
Upvotes: 0
Reputation: 21
I would expect the issue to be in the else in the gothere2 case. It is not authenticating and is promised to return a Boolean. However you are not returning anything. Where in the authentication case you are. How I would fix:
(authenticated: boolean) => {
if (authenticated) {
console.log(`got here1`)
return true;
} else {
console.log(`got here2`)
this.router.navigate(['/recipes']);
return false;
}
Upvotes: 2
Reputation: 956
Assuming you are using the version >=7. Try to replace
this.router.navigate(['/recipes']);
with
return this.router.parseUrl('/recipes');
You may also get rid of
: Observable<boolean> | Promise<boolean> | boolean
as typescript will be able to infer it.
Upvotes: -1