RXJS pipe与map处理Angular HTTP登录请求的报错及用法疑问
修复后的可运行代码
// 给http.post指定返回泛型,明确返回值类型 this.http.post<UserAuthenticatedDto>(this.baseUrl + 'account/login', dto) .pipe( // 用tap处理副作用操作,不修改数据流 tap(val => { this.toastr.success("Logged In Successfully", "", { positionClass: 'toast-bottom-right' }); this.route.navigateByUrl('/splashPagePost'); }), // map仅负责数据转换,生成目标DTO实例 map(val => { const userDto = new UserAuthenticatedDto(); userDto.username = val.username; userDto.token = val.token; userDto.roles = val.roleslist; userDto.knownAs = val.knownAs; return userDto; }) ) // 必须订阅才会触发实际的HTTP请求 .subscribe();
问题1:副作用操作的存放规范
map是纯转换操作符,设计用途是对上游数据流做无副作用的格式转换,不要在内部放置toastr提示、路由跳转这类副作用逻辑。- RXJS提供了专门的
tap操作符处理这类不需要修改数据流的副作用操作,放在tap中执行即可,不会影响后续流的传递。 - 额外注意:你当前的代码没有添加
subscribe()调用,Angular的HttpClient返回的是冷Observable,不订阅的话请求根本不会发出。
问题2:属性找不到、代码不可达的根因
- 语法错误:你写的
return new UserAuthenticatedDto;后面直接跟了分号,代码执行到这一行就直接返回了,后面大括号里的所有逻辑完全不会执行,这是代码不可达报错的直接原因。 - 类型问题:
http.post默认返回类型是Object,你需要显式指定泛型参数this.http.post<UserAuthenticatedDto>(xxx),Typescript才能识别返回值val的类型,不会提示找不到属性。 - 逻辑错误:你需要先实例化DTO对象,完成所有属性赋值后再return,不能先执行return再做赋值操作。
- 拼写问题:如果你手动标注val类型时拼写了错误的DTO名称(你写的
UserAuthentcatedDto比正确名称少了一个字母t),也会导致类型校验不生效,注意检查类型名称的拼写是否一致。
内容的提问来源于stack exchange,提问作者Yogi Bear
相关产品推荐
相关产品推荐

