我在Angular 2中开始一个项目,我第一次与Observables交易并对一个非常具体的案例有一些疑问。
我有一个API服务,如下所示:
@Injectable()
export class UserAPI {
[...]
login(email: string, password: string): Observable<Response> {
let params = new URLSearchParams();
params.set('email', email);
params.set('password', password);
return this.$http.request(
new Request({
method: RequestMethod.Post,
url: this.baseUrl + '/login',
search: params
}))
.map((response: Response) => response.json());
}
[...]
}
我在包含调用此API的方法的用户服务上管理用户会话及其配置文件数据(当其会话处于活动状态时):
@Injectable()
export class UserService {
[...]
constructor(private userAPI: UserAPI, private storage: StorageService) {
}
login(email: string, password: string) {
return this.userAPI.login(email, password).subscribe(
(res) => {
this.storage.store(Constants.storage.session, res.token);
},
(err) => {
this.storage.destroy(Constants.storage.session);
}
);
}
[...]
}
现在,我还有一个处理登录表单的组件,如果成功,会将用户重定向到应用程序的私有区域,但如果失败,将显示错误消息(401,或者任何其他错误,如果偶然发生):
@Component({
moduleId: module.id,
selector: "auth-login",
templateUrl: "auth.login.html"
})
export class LoginComponent {
constructor(private router: Router, private userService: UserService) {
}
[...]
login(): void {
this.form.loading = true;
this.form.error = -100; // arbitrary number
this.userService.login(this.form.email, this.form.password);
/*
.subscribe(
(res) => {
this.router.navigate(["/home", {}]);
},
(err) => {
this.form.error = err.status;
},
() => {
this.form.loading = false;
}
);
*/
}
[...]
}
请注意userService.login()
函数调用上的注释代码。这些是我打算对电话的成功/错误做的指示,但是我不能让它发挥作用。我希望将事物分开:用户服务管理会话部分,组件处理重定向或向用户显示出错的地方。
我做错了什么?什么方式去这里?嵌套的可观察物?使用组件和用户服务之间的承诺?还有其他方法吗?我一直在这里搜索,但找不到与我相似的案例。
答案 0 :(得分:2)
我认为你不能把这样的订阅链接起来;你实际上期望thing.subscribe(...).subscribe(...)
能够工作。相反,您可以使用.map
和.catch
进行服务中的操作,并让组件.subscribe
:
login(email: string, password: string) {
return this.userAPI.login(email, password)
.map(res => {
this.storage.store(Constants.storage.session, res.token);
return res;
})
.catch(err => {
this.storage.destroy(Constants.storage.session);
return Observable.throw(err);
});
}