Angular5登录功能实现报错:TypeError: 期望传入流却得到undefined
解决Angular5登录功能中的TypeError: You provided 'undefined' where a stream was expected错误
这个错误在Angular + RxJS的开发场景里太常见了,本质就是你在需要一个“流”(Observable/Promise/数组/可迭代对象)的位置传入了undefined。结合你做登录功能的场景,大概率和你的UserService登录方法或者组件中调用该方法的逻辑有关,下面给你几个最可能的排查方向和解决办法:
1. 优先检查UserService的login方法是否正确返回Observable
这是触发该错误的最常见原因——很多人写服务方法时会忘记return HTTP请求的Observable。比如你可能在user.services.ts里写了这样的错误代码:
login(userCredentials) { // 只调用了http.post,但没有return这个Observable! this.http.post('/api/auth/login', userCredentials); }
正确的写法必须要return这个HTTP请求返回的Observable,这样组件才能正常订阅它:
import { Observable } from 'rxjs/Observable'; // ...其他必要导入 @Injectable() export class UserService { constructor(private http: HttpClient) {} login(userCredentials): Observable<any> { // 一定要return这个流 return this.http.post('/api/auth/login', userCredentials); } }
2. 检查组件中订阅登录流时的操作符使用
如果你的组件里在调用login方法后用了pipe操作符(比如map、switchMap),要确保这些操作符内部没有返回undefined。比如错误示例:
onSubmit(form: NgForm) { this.userService.login(form.value).pipe( map(response => { // 这里如果没有return任何值,就会把流变成undefined localStorage.setItem('token', response.token); // 忘记return response了! }) ).subscribe( res => this.router.navigate(['/dashboard']), (err: HttpErrorResponse) => console.error(err) ); }
如果只是要执行副作用(比如存token),不需要转换流数据的话,用tap操作符更合适,它不会改变流的内容:
import 'rxjs/add/operator/tap'; // ... onSubmit(form: NgForm) { this.userService.login(form.value).pipe( tap(response => { localStorage.setItem('token', response.token); }) ).subscribe( () => this.router.navigate(['/dashboard']), (err: HttpErrorResponse) => console.error(err.message) ); }
如果确实需要转换数据,一定要确保map操作符return一个有效值。
3. 排查是否误用了RxJS切换类操作符
如果你用了switchMap、mergeMap这类需要内部返回Observable的操作符,也可能因为内部没返回流而触发错误。比如:
this.userService.login(form.value).pipe( switchMap(loginRes => { // 这里如果没有return一个Observable,就会导致流变成undefined this.userService.getUserInfo(loginRes.userId); }) ).subscribe(...);
正确的做法是确保内部return一个Observable:
this.userService.login(form.value).pipe( switchMap(loginRes => { return this.userService.getUserInfo(loginRes.userId); }) ).subscribe(...);
先从这几个方向排查,尤其是第一个,90%的概率是服务方法没return Observable导致的。
内容的提问来源于stack exchange,提问作者Pracede
相关产品推荐
相关产品推荐

