如何根据另一个可观察对象的结果订阅(或不订阅!)一个可观察对象
How to subscribe (or not!) to an observable depending of the result of another observable
使用 angular 10,在服务中,我有方法 getCurrentUser() 对我的 api 和 return 当前用户进行 http 调用作为可观察的(其中之一属性 是“isAdmin:boolean”),我有其他服务,我想在其中创建方法 getAllUsers ,该方法 return 所有用户列表 (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() 的 return,因为如果用户不是管理员,有时它不会 return 任何东西。使用简单的“else throw new Error()”我得到了一个编译器错误,因为我声明 getAllUsers() 应该 return 一个 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;
}
})
}
}
如果用户不是管理员,一个简单的解决方案是 return null,方法是分离两个调用(getAdmin() 和 getAllUsers())。
@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);
});
}
});
}
你犯的一个错误是 return 不是放在 Observable 上而是放在 Observable 结果上。
this.service.getUser().pipe(
switchMap(user => user.isAdmin
? this.service.getAllUsers().pipe(users => [user, users])
: of([user])
)
).subscribe(([user, users]) => ... ) // users will be undefined if not admin
即使先例 post 回答了我的问题,我在这里 post 另一个对我有用的答案:有人告诉我,在这种情况下,好的概念是使管理逻辑在一个守卫,并在使用后台服务的组件的路由中添加这个守卫。
效果很好,似乎是很好的做法。
使用 angular 10,在服务中,我有方法 getCurrentUser() 对我的 api 和 return 当前用户进行 http 调用作为可观察的(其中之一属性 是“isAdmin:boolean”),我有其他服务,我想在其中创建方法 getAllUsers ,该方法 return 所有用户列表 (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() 的 return,因为如果用户不是管理员,有时它不会 return 任何东西。使用简单的“else throw new Error()”我得到了一个编译器错误,因为我声明 getAllUsers() 应该 return 一个 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;
}
})
}
}
如果用户不是管理员,一个简单的解决方案是 return null,方法是分离两个调用(getAdmin() 和 getAllUsers())。
@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);
});
}
});
}
你犯的一个错误是 return 不是放在 Observable 上而是放在 Observable 结果上。
this.service.getUser().pipe(
switchMap(user => user.isAdmin
? this.service.getAllUsers().pipe(users => [user, users])
: of([user])
)
).subscribe(([user, users]) => ... ) // users will be undefined if not admin
即使先例 post 回答了我的问题,我在这里 post 另一个对我有用的答案:有人告诉我,在这种情况下,好的概念是使管理逻辑在一个守卫,并在使用后台服务的组件的路由中添加这个守卫。 效果很好,似乎是很好的做法。