Angular+RxJS文件上传报错:You provided 'undefined' where a stream was expected
解决Angular文件上传的"You provided 'undefined' where a stream was expected"错误
核心问题排查与修复
1. 确保HttpClient正确注入
这是最可能触发该错误的原因:如果上传服务中未注入HttpClient,this.http会是undefined,调用this.http.request时会抛出错误,导致upload函数返回undefined,最终forkJoin接收到无效的流。
修改服务类,必须在构造函数中注入HttpClient:
import { HttpClient, HttpRequest } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable, of } from 'rxjs'; import { catchError } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class UploadService { constructor(private http: HttpClient) {} // 关键:注入HttpClient upload(file: File): Observable<any> { const formData: FormData = new FormData(); const url = `some_url`; if (file) { formData.append('file', file, file.name); } const req = new HttpRequest('POST', url, formData); return this.http.request(req) .pipe( catchError((error): Observable<any> => { // 先判断file是否存在,避免访问name时出错 const fileName = file ? file.name : '未知文件'; return of({err: error, fileName, failed: true}); }) ); } }
2. 修复catchError中的潜在异常
在catchError回调中,直接访问file.name可能因file为undefined抛出错误,导致无法返回有效Observable,需先做判断:
catchError((error): Observable<any> => { const fileName = file ? file.name : '未知文件'; return of({err: error, fileName, failed: true}); })
3. 保证forkJoin接收有效Observable数组
在组件的sendFiles方法中,过滤无效文件,确保只传递有效的Observable给forkJoin:
sendFiles(files: File[]): Observable<unknown> { // 过滤掉非File类型的无效项 const uploadObservables = files .filter(file => file instanceof File) .map(file => this.uploadService.upload(file)); // 空数组时返回发出空数组的Observable,避免forkJoin无响应 return uploadObservables.length > 0 ? forkJoin(uploadObservables) : of([]); }
4. 完善组件文件选择逻辑
增强文件输入的有效性判断,避免传递无效的文件列表:
onFilesSelected(event: Event) { const input = event.target as HTMLInputElement; if (!input.files || input.files.length < 1) { return; } const files = Array.from(input.files) as File[]; this.sendFiles(files).subscribe({ next: fileUploads => { this.fileUploads = fileUploads; }, complete: () => { console.log("上传结果", this.fileUploads); } }); }
内容的提问来源于stack exchange,提问作者kasif adnan
相关产品推荐
相关产品推荐

