Angular2 + redirectTo not working when redirecting to link using canActivate

redirectTo

failed to redirect link from canActivate

at login.

redirectTo

works great on logout, it redirects my component /login

and redirectTo

in /index

after login.

But it clicks ''

when I am logged in.

I added console.log

to mine authGuard

, and the redirect url / index "put this function in a stick at a ''

glitch-free position in the development tool.

But after comments canActivate

, it redirectTo

works fine as before.

BTW, my authGuard s canActivate

works fine in other situations (exclude redirecTo

)

Here's my app-routing.module.ts

/* import... */

const appRoutes: Routes = [
    { path: 'login', component: LoginComponent },
    { path: '', redirectTo : '/index', pathMatch: 'full' },
    { path: '**', component: PageNotFoundComponent }
];

/* ngmodel and export ... */

      

and here's my index-routing.module.ts

/* import ... */

const indexRoutes: Routes = [
    {
        path: 'index',
        component: IndexComponent,
        canActivate: [AuthGuard], //<- if comment this will work
    },
];

/*   ngmodel and export ... */

      

here's my auth-guard.module.ts

/* import ... */

@Injectable()
export class AuthGuard implements CanActivate {
    constructor(
        private authService: AuthService,
        private router: Router
    ) { }
    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        let url: string = state.url;
        //redirectTo did get in here
        console.log(url); //<-- this show /index 

        return this.checkLogin(url);
    }

    checkLogin(url: string): boolean {
        if (this.authService.login_data && (this.authService.login_data.userprofile || !this.authService.login_data.need_login)) {
            return true;
        }
        this.authService.get_login_data()
         .subscribe(
            data => {
                this.authService.login_data = data;
                if (data.userprofile || !data.need_login) {
                    return true;
                }
                this.authService.redirectUrl = url;
                this.router.navigate(['/login']);
                return false;
            },
            error => { this.authService.errMsg = <any>error;}
        );
    }
}

      

By the way, I updated my project to angular4.0.1

Thank.

UPDATE:

I changed my guard return from boolean to Observable

but it still doesn't work.

here's the code i used.

    checkLogin(url: string): Observable<boolean> {
        if (this.authService.login_data && (this.authService.login_data.userprofile || !this.authService.login_data.need_login)) {
            console.log('gonna return observable true');
            return Observable.of(true);
            //return true;
        }
        this.authService.get_login_data()
        .subscribe(
            data => {
                this.authService.login_data = data;
                if (data.userprofile || !data.need_login) {
                    console.log('in subscribe and gonna return observable true');
                    return Observable.of(true);
                    //return true;
                }
                this.authService.redirectUrl = url;
                this.router.navigate(['/login']);
                return Observable.of(false);
                //return false;
            },
            error => { this.authService.errMsg = <any>error;}
        );
    }

      

In my console I got in subscribe and gonna return observable true

UPDATE:

after checking after checking this

AuthGuard does not wait for authentication to complete before verifying the user

the problem might be canActivate

not waiting for the end of the subscription.

+3


source to share


2 answers


In checkLogin()

AuthGuard

:

checkLogin(url: string): boolean {
    if (this.authService.login_data && (this.authService.login_data.userprofile || !this.authService.login_data.need_login)) {
        return true;
    }
    this.authService.get_login_data()
     .subscribe(
        data => {
            this.authService.login_data = data;
            if (data.userprofile || !data.need_login) {
                return true;
            }
            this.authService.redirectUrl = url;
            this.router.navigate(['/login']);
            return false;
        },
        error => { this.authService.errMsg = <any>error;}
    );
}

      

it returns boolean type, it returns true, in some state, that's ok. But, the later part has some problems. You didn't return anything until you signed the result and returned based on that result.

This means that this function will return undefined, so the canActivate check will not work.



[Updated] You want to set user data from the result, you have to use do()

in yours authService.get_login_data()

to set it. When you subscribe to the result, this "do" function will be called. And in checkLogin()

use .map()

instead subscribe()

to match the input result data to boolean.

In this situation, you must return the Observable type, for example:

checkLogin(url: string): Observable<boolean> {
if (this.authService.login_data && (this.authService.login_data.userprofile || !this.authService.login_data.need_login)) {
    return Observable.of(true); // wrap true in Observable
}
return this.authService.get_login_data()
 .map(
    data => {
        if (data.userprofile || !data.need_login) {
            return true;
        }
        this.authService.redirectUrl = url;
        this.router.navigate(['/login']);
        return false;
    },
    error => { this.authService.errMsg = <any>error;}
);

      

}

0


source


I solved my problem by changing my card subscription.

Angular2 canActivate () function to call async function

here's my code after editing.

checkLogin(url: string): Observable<boolean>|boolean {
    if (this.authService.login_data && (this.authService.login_data.userprofile || !this.authService.login_data.need_login)) {
        console.log('gonna return observable true');
        return Observable.of(true);
    }   
    return this.authService.get_login_data()
    .map(
        data => {
            this.authService.login_data = data;
            if (data.userprofile || !data.need_login) {
                console.log('in subscribe and gonna return observable true');
                //return Observable.of(true);
                return true;                                                                                                                                                
            }   
            this.authService.redirectUrl = url;
            this.router.navigate(['/login']);
            //return Observable.of(false);
            return false;
        },  
        error => { this.authService.errMsg = <any>error;}
    );  
}  

      



on the map i got an error if i return Observable (true)

Type 'Observable<Observable<boolean>>' is not assignable to type 'boolean | Observable<boolean>'.

Thanks for the help and suggestions.

0


source







All Articles