以角度嵌套订阅

时间:2021-07-11 09:50:10

标签: angular typescript

这是我的代码..我需要检查 2 个可观察数据..它适用于 1 个可观察数据如何检查另一个可观察数据

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, Router, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
import { filter, map, take } from 'rxjs/operators'
import { AuthenticationService } from '../services/authentication.service';

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate  {

  constructor(private authService: AuthenticationService, private router: Router) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):  Observable<boolean> | Promise<boolean> | boolean
  {
    
    return this.authService.isAuthenticated.pipe(
      filter(val => val !== null), // Filter out initial Behaviour subject value
      take(1), // Otherwise the Observable doesn't complete!
      map(isAuthenticated => {
        if (isAuthenticated) {  

  TRY 1...........Initial code with direct access without observable but it is not working after login it is not navigate ..if i refresh (f5) then this works
     if( state.url !== '/changepassword'   &&  this.authService.getUserValue.changePassword)
               this.router.navigateByUrl('/changepassword');               
                return true;
----------------------------------------------

         // TRY 2 //Added conditional if 
          -----------------------------------------------------------
           ///i need to subscibe another value and if value is true the route to change 
            password else dashboard should load
           this.authService.getUserValueObs().pipe(
            filter(val => val !== null), // Filter out initial Behaviour subject value
            take(1),
            map(user =>{
                if( state.url !== '/changepassword'   &&  user.changePassword)
                    this.router.navigateByUrl('/changepassword'); 
                }
             ));
            ----------------------------------------------------
           return true;   // i need to retun this value after subscibe of inner observble...
        } else {          
          this.router.navigateByUrl('/')
          return false;
        }
      })
    );
  }
}

当前的 AuthGuard 代码工作正常,但如果应该加载仪表板更改密码页面的订阅值,我需要添加另一个条件?如何执行多个订阅方法

编辑:

这是我的身份验证服务类 * 方法..

 export class AuthenticationService {
 
   isAuthenticated: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(null);
 
   userSubject$= new  BehaviorSubject<IAuthenticatedUser>(undefined);

  get getUserValue(): any  {
    return this.userSubject$.value;
  }

  getUserValueObs(): Observable<IAuthenticatedUser>  {
    return this.userSubject$.asObservable();
  }

      login(credentials: {userName:string, password:string}): Observable<any> {
            return this.http.post(`${baseUrl}/authenticate-app`, credentials).pipe(
               map((result: any) => result.data),
               switchMap((user: {userId,userName, fullName refreshToken}) => { 
                if(user)
                    return this.storeUserData(user);
                 }
                  
              }), 
              tap(_ => {
                this.isAuthenticated.next(true);
              })
            )

}

当前的问题是在登录时我正在为两个行为主题赋值...但是 Ispasswordchange 有一段时间没有得到值...如果我刷新然后值来

1 个答案:

答案 0 :(得分:2)

如果你想从一个 observable 切换到另一个并使用前一个 observable 的值,你可以使用 switchMap 运算符:

return this.authService.isAuthenticated.pipe(
  filter((val) => val !== null), // Filter out initial Behaviour subject value
  take(1), // Otherwise the Observable doesn't complete!
  switchMap((isAuthenticated) => {
    if (isAuthenticated) {
      return this.authService.getUserValueObs().pipe(
        filter((val) => val !== null), // Filter out initial Behaviour subject value
        take(1),
        map((user) => {
          if (state.url !== "/changepassword" && user.changePassword)
            return this.router.navigateByUrl("/changepassword");
          return true;
        })
      );
    } else {
      return this.router.navigateByUrl("/");
    }
  })
);