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.
I cannot get the syncronized value from the authService. This is my code:
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
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.
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.
Here's the correct 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;
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.