首页 > 解决方案 > 如何根据另一个 observable 的结果订阅(或不订阅!)一个 observable

问题描述

使用角度 10,在服务中,我有方法 getCurrentUser(),它对我的​​ api 进行 http 调用以将当前用户返回为可观察的(其中一个属性是“isAdmin:boolean”),我有这个其他服务在哪里我想创建 getAllUsers 方法,该方法将返回所有用户的列表 (user[]) 也是可观察的,但前提是当前用户是管理员 (user.isAdmin = true)。我用 rxjs 运算符尝试了一些东西,比如 map、switchMap 和 flatMap,但我觉得我完全错了,你能给出一些提示吗?

这是我在第二项服务中尝试的:

@Injectable({
    providedIn: "root",
})
export class BackofficeService {

    constructor(private http: HttpClient, private userService: UserService) {}

    public getAllUsers(): Observable<User[]> {
        this.userService.getCurrentUser().pipe(
            map((user: User) => {
                if (user.roles.includes("admin")) {
                    return this.http.get<User[]>("/api/settings/users/all");
                } else throw new Error("User not admin.");
            })
        );
    }
}

我也不知道如何管理 getAllUsers() 的返回,因为如果用户不是管理员,有时它不会返回任何内容。使用简单的“else throw new Error()”,我得到了一个编译器错误,因为我声明 getAllUsers() 应该返回一个 Observable。

然后在我的组件中我这样做:

@Component({
    selector: "app-users",
    templateUrl: "./users.component.html",
})
export class UsersComponent implements OnInit {
  public usersList: User[];
  constructor(private boService: BackofficeService) {}

    ngOnInit(): void {
    this.boService
      .getAllUsers()
      .subscribe((users?: User[]) => {
        if(users){
          this.usersList = users;
        }
      })
    }
}

标签: angularrxjs-observables

解决方案


一个简单的解决方案是,如果用户不是管理员,则通过分离两个调用(getAdmin() 和 getAllUsers())来返回 null。

@Injectable({
    providedIn: "root",
})
export class BackofficeService {

    constructor(private http: HttpClient, private userService: UserService) {}

    public getAdmin(): Observable<User> {
        return this.userService.getCurrentUser().pipe(
            map((user: User) => {
                if (user.roles.includes("admin")) {
                    return user;
                } else {
                    return null;
                }
            })
        );
    }
    
    public getAllUsers(): Observable<User[]> {
        return this.http
            .get<User[]>("/api/settings/users/all").pipe(
            map((users: User[]) => users);
    }
}

然后在组件中订阅两者,仅当第一个给出预期结果时才订阅第二个:

  ngOnInit(): void {
    this.boService
      .getAdmin()
      .subscribe((user: User) => {
        if (user) {
          this.boService
            .getAllUsers()
            .subscribe((users: User[]) => {
              console.log(users);
            });
        }
      });
  }

您犯的一个错误是将返回值放在 Observable 上,而不是放在 Observable 结果上。


推荐阅读