admin管理员组

文章数量:1416050

In my angular routing module, I am using a base navigation when its the default homepage, now on some condition, I want to decide which route to navigate. This is how my app routing looks.

 { path: '', redirectTo: 'home1', canActivate: [homepageGuard], pathMatch: 'full' },
  { path: 'home1', loadChildren: './lazyloadedmodule1' },
  { path: 'home2', loadChildren: './lazyloadedmodule2' },
  { path: 'home3', loadChildren: './lazyloadedmodule3' },
  { path: 'basehome', loadChildren: './lazyloadedmodule4' }

In my angular routing module, I am using a base navigation when its the default homepage, now on some condition, I want to decide which route to navigate. This is how my app routing looks.

 { path: '', redirectTo: 'home1', canActivate: [homepageGuard], pathMatch: 'full' },
  { path: 'home1', loadChildren: './lazyloadedmodule1' },
  { path: 'home2', loadChildren: './lazyloadedmodule2' },
  { path: 'home3', loadChildren: './lazyloadedmodule3' },
  { path: 'basehome', loadChildren: './lazyloadedmodule4' }

Now in my route guard, I am calling the subscription like this.

canActivate(): Observable<any> | boolean {
    return this._myService.getCurrentApp().subscribe(
      (r) => {
        if(r === 'app1'){
          //navigate to app1homepage
        } else if (r === 'app2') {
          //navigate to app2homepage
        } else {
          // navigate to base homepage
        }
      },
      (e) => {
        console.log(e);
        return false;
      }
    );
  }

This is how my service looks where I call the API.

public getCurrentApp(): Observable<any> {
    return this.http.get(this.apiBaseUrl + 'getApp').pipe(
      catchError((err: HttpErrorResponse) => {
        return throwError(err.error.errorMessage);
      }));
  }

Firstly the routeguard is not taking the value as subscription, because I believe its expecting just a boolean, but i will be getting the response as string back. How do I make sure that during the first page load, its calling the API, and redirecting it accordingly?

Share Improve this question asked Apr 26, 2019 at 21:47 AijazAijaz 73019 silver badges50 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

I propose something like this. Use service and return true/false & navigate.

canActivate(): Observable<any> | boolean {
return this._myService.getCurrentApp()
    pipe(
        tap((response) => {
            if(r === 'app1'){
                this.router.navigate([...]);
            } else if (r === 'app2') {
                this.router.navigate([...]);
            } else {
                this.router.navigate([...]);
            }
        }),
        map(() => false),
        catchError((e)=> of(false))
    )
    }
  }

Frankly writing, that's not the best solution for such issue. I believe that a better approach would be to create different AuthGuards for the different path which will do API request and check if it is allowed to go to a specific route. Then only return false or true.

Your guard should not subscribe to the observable, the router does that....

So you basically need to return an observable that returns a value of true or false.

If you're going to reroute, then you will obviously never return true.... try this....

canActivate(): Observable<boolean> {
    return this._myService.getCurrentApp().pipe(
        tap(r => {
            if(r === 'app1'){
                //navigate to app1homepage
            } else if (r === 'app2') {
               //navigate to app2homepage
            } else {
               // navigate to base homepage
            }
        }),
        catchError(r => of(false))
    );
}

本文标签: javascriptHow to use an Observable in Angular route guardStack Overflow