rxjs observable ajax,redux-observable use RxJS to emit progress actions for ajax call

I have been wrestling with this problem and feel like I have a fundamental misunderstanding. I am using the redux-observable library in React which glues redux together with RxJS for handling asynchrony. My problem is that I have to handle a large upload and I want to show progress as the file is loaded.

The function uploadFileEpic needs to return an Observable to work with redux-observable. The uploadObservable represents the workflow that I want to accomplish. If I just return the uploadObservable the upload works but I don't get any handleUploadFileProgress actions from the progressSubscriber in the ajax call. Ideally the progressSubscriber would be adding elements to another observable that I could merge with uploadObservable. You see me trying to use merge here but the TypeScript compiler complains saying the return is not assignable to an ObservableInput.

I keep going in circles so I feel my understanding must be fundamentally off. I feel like I'm missing some simple RxJS magic here. Thanks for the help!

import { Observable, Observer, Subscriber, Subject, of } from 'rxjs';

import { ajax } from 'rxjs/ajax';

import { ofType } from 'redux-observable';

import { catchError, delay, map, mergeMap, tap, merge } from 'rxjs/operators';

import { apis } from '../../config';

export const enum ActionType {

InitialFileUpload

FileProgress

UploadFileSuccess

UploadFileFail

}

const handleInitialFileUpload = (file: File, timeLimit: number) => ({

type: ActionType.InitialFileUpload,

file,

timeLimit

})

const handleFileProgress = (file: File, percentComplete: number) => ({

type: ActionType.FileProgress,

file,

percentComplete

})

const handleUploadFileSuccess = (file: File, timeLimit: number) => ({

type: ActionType.UploadFileSuccess,

file,

timeLimit

})

const handleUploadFileFail = (file: File, timeLimit: number) => ({

type: ActionType.UploadFileFail,

file,

timeLimit

})

export const uploadFileEpic= action$ =>

action$.pipe(

ofType(ActionType.InitialFileUpload),

mergeMap((action: any) => {

const { file, timeLimit } = action;

const data = new FormData()

data.append('importFile', file, file.name)

data.append('timeLimit', timeLimit)

const progressSubject = new Subject();

const ajaxRequest = {

url: apis.gateway.run,

method: 'POST',

body: data,

headers: {},

progressSubscriber: Subscriber.create(

(e: ProgressEvent) => {

const percentComplete = Math.round((e.loaded / e.total) * 100)

console.log("Progress event")

progressSubject.next(handleUploadFileProgress(file, percentComplete))

}

)

}

const uploadObservable = ajax(ajaxRequest)

.pipe(

map(res => handleUploadFileSuccess(file)),

delay(SUCCESSFUL_UPLOAD_NOTIFICATION_LENGTH),

map(() => handleUploadFileRemove(file)),

catchError(error => of(handleUploadFileFail(file, error.response)))

)

return merge(uploadObservable, progressSubject)

}

)

)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值