Mark Nelson
Mark Nelson

Reputation: 11

Error: Uncaught (in promise): [object Boolean]

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

Answers (5)

Reaper
Reaper

Reputation: 412

Sometime you get error due to catch try to open it in incognito mode

Upvotes: 0

Dipin raman
Dipin raman

Reputation: 183

I have tried it out from my end was getting the same error and this is how i fixed it. enter image description here

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 enter image description here

In order to prevent this error we need to catch it as shown below. enter image description here

Now i am not getting any error. enter image description here

Upvotes: 1

Mohammad Umair Khan
Mohammad Umair Khan

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

Jim
Jim

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

Bill Cheng
Bill Cheng

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

Related Questions