简体   繁体   English

角度4:无法从CanActivate AccessGuard订阅可观察的值

[英]Angular 4: cannot subscribe observable value from CanActivate AccessGuard

i followed a lot of tutorials and tried many combinations but cannot make this work. 我遵循了很多教程,并尝试了许多组合,但无法完成这项工作。

I need to let a route be available when a user is logged. 登录用户时,我需要让路由可用。 If he's not i need to redirect him to the homepage (this._popupService.setCallbackRoute(route.url.join('/'))) and show a popup (this._popupService.showPopUp()) which lets him login or register. 如果不是他,我需要将他重定向到首页(this._popupService.setCallbackRoute(route.url.join('/')))并显示一个弹出窗口(this._popupService.showPopUp()) ,以便他登录或注册。

I cannot get the syncronized value from the authService. 我无法从authService获取同步值。 This is my code: 这是我的代码:

app.module.ts app.module.ts

imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    RouterModule.forRoot(
        {path: '', component: HomepageComponent},
        {
            path: 'protectedRoute',
            component: SubmitComponent,
            data: {requiresLogin: true},
            canActivate: [AccessGuard]
        }
    ),
    ...
]

auth.service.ts 验证服务

 @Injectable()
export class AuthService {

    private loggedIn: Subject<boolean> = new Subject<boolean>();

    get isLoggedIn() {
        return this.loggedIn.asObservable();
    }

    login(user: IUser) {
        return this._http.get('assets/api/responseSuccess.json?email=' + user.email + '&password=' + user.password)
            .map((responseLogin => {
                const jsonResponse = responseLogin.json();
                if (jsonResponse.response === 'success') {
                    const userResponse: IUser = jsonResponse.user;
                    this._sessionService.setUserSession(userResponse);
                    this.loggedIn.next(true);
                    return true;
                } else {
                    this._customFlashMessages.show('Got error login, please check your credentials and try again!');
                    return false;
                }
            }));
    }
}

accessGuard.service.ts accessGuard.service.ts

import {Injectable} from '@angular/core';
import {ActivatedRouteSnapshot, CanActivate, Router} from '@angular/router';
import {Observable} from 'rxjs/Observable';
import {AuthService} from './auth.service';
import {PopUpService} from './popup.service';

@Injectable()
export class AccessGuard implements CanActivate {
    loggedIn$: Observable<boolean>;

    constructor(private authService: AuthService, private _popupService: PopUpService, private router: Router) {
        this.loggedIn$ = this.authService.isLoggedIn;
    }

    canActivate(route: ActivatedRouteSnapshot): Observable<boolean> | Promise<boolean> | boolean {
        const requiresLogin = route.data.requiresLogin || false;
        if (requiresLogin) {
            this.authService.isLoggedIn.subscribe( // even tried with .map()
                result => {
                    console.log(result); // Logs a promise object
                    if (!result) {
                        console.log("protected route"); // Never reached
                        // If not logged in shop popup and stay on that page
                        this._popupService.showPopUp();
                        this._popupService.setCallbackRoute(route.url.join('/'));
                        return false;
                    }
                    console.log('logged in'); // Never reached
                    return true;
                });
        }
        return true;
    }
}

I tried several things. 我尝试了几件事。 My code works if i directly check the sessionStorage('user') but not working with observable. 如果我直接检查sessionStorage('user')但不能使用observable,则我的代码有效。

Any help is appreciated. 任何帮助表示赞赏。

Thank you! 谢谢!

You need to return an observable. 您需要返回一个可观察值。

canActivate(route: ActivatedRouteSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    const requiresLogin = route.data.requiresLogin || false;
    if (requiresLogin) {
        return this.authService.isLoggedIn;
    }
    return Observable.of(false);
}

This is the correct answer, the problem was in the logic inside the subscribe method. 这是正确的答案,问题出在subscribe方法内部的逻辑中。

Here's the correct accesGuard.service.ts 这是正确的accesGuard.service.ts

@Injectable()
export class AccessGuard implements CanActivate {

    constructor(private authService: AuthService, private _popupService: PopUpService, private router: Router) {
    }

    canActivate(route: ActivatedRouteSnapshot): Observable<boolean> | Promise<boolean> | boolean {
        const requiresLogin = route.data.requiresLogin || false;
        if (requiresLogin) {
            this.authService.isLoggedIn.subscribe(
                result => {
                    if (!result) {
                        // If not logged in shop popup and stay on that page
                        this._popupService.showPopUp();
                        this._popupService.setCallbackRoute(route.url.join('/'));
                        this.router.navigate(['/']);
                        return false;
                    }
                    return true;
                });

            return true;
        }else{

        return true;
       }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM