通过switchmap处理ngrx效果中的多个api调用

问题描述 投票:0回答:1

我正在尝试使用 switchmap 在 ngrx 效果中执行多个 API 调用

该操作需要输入要上传的文件数组,并且 api 支持一次一个文件

我的效果如下

uploadFiles$ = createEffect(() =>
        this.actions$.pipe(
            ofType(uploadFiles),
            switchMap(({id, files}) => {

                const uploadApiList = []
                for(let i =0 ; I<files ; i++) {
                    uploadApiList.push(this.apiService.uploadFile(id, files[i]));
                }
                 return uploadApiList;
    
            }), 
            tap(result=> console.log(result ),
            tap(res=> {return uploadFilesSuccess({response: res})}),
            catchError(error => of(uploadFailure({ errorResponse: error })))
        ),
            { dispatch: false }
    );

服务方式

public uploadFile(id: string, file: File): Observable<any> {
        console.log('***************')
        const formData: FormData = new FormData();
        formData.append('file', file);

        return new Observable(observer => {
        
            this.store.dispatch(showLoadingMask());
            this.httpClient.post<any>(`${this.baseUrl}/${id}/upload-files`, formData).subscribe(
                (response: HttpResponse<any>) => {
                    console.log(formData)
                    observer.next(response?.body);
                    observer.complete();
                    this.store.dispatch(hideLoadingMask());
                },
                error => {
                    this.logService.error('[UNEXPECTED_RESPONSE]', error);
                    observer.error(error);
                    observer.complete();
                    this.store.dispatch(hideLoadingMask());
                }
            );
        });
    }

但是 api 永远不会被调用,结果会打印为 Observables 数组,我也可以看到我调用的方法,但 http 调用没有发生

我不知道我做错了什么?

rxjs ngrx ngrx-effects switchmap
1个回答
0
投票

我对

ngrx
没有太多经验,但我们需要对可观察数组(
forkJoin
)执行
uploadApiList
来获取内部值,也不需要在
uploadFile 内进行订阅
,我们可以只使用
map
catchError

另外,

tap
不接受返回值(
uploadFilesSuccess({response: res})
),所以我将其更改为接受返回值的
map

uploadFiles$ = createEffect(() =>
    this.actions$.pipe(
        ofType(uploadFiles),
        switchMap(({id, files}) => {
            this.store.dispatch(showLoadingMask());
            const uploadApiList = [];
            files.forEach((file: any) => {
                uploadApiList.push(this.apiService.uploadFile(id, file));
            });
            return forkJoin(uploadApiList);
        }), 
        tap(result=> {    
            this.store.dispatch(hideLoadingMask());
            console.log(result);
        }),
        map(res => {
            return uploadFilesSuccess({response: res});
        }),
        catchError(error => { 
            this.store.dispatch(hideLoadingMask());
            return of(uploadFailure({ errorResponse: error }))
        }),
    ),
        { dispatch: false }
);

服务:

public uploadFile(id: string, file: File): Observable<any> {
    console.log('***************')
    const formData: FormData = new FormData();
    formData.append('file', file);

    return this.httpClient.post<any>(`${this.baseUrl}/${id}/upload-files`, formData).pipe(
        map((response: HttpResponse<any>) => {
            return response?.body;
        },
        catchError(error => {
            this.logService.error('[UNEXPECTED_RESPONSE]', error);
            throw error;
        }),
    );
}
© www.soinside.com 2019 - 2024. All rights reserved.