Hi guys)
Could someone suggest me how I can call a callback promise ?
I use react-native-fs and downloadFile func.
This from RNFS documentation:
downloadFile(options: DownloadFileOptions): { jobId: number, promise: Promise<DownloadResult> }
type DownloadFileOptions = {
fromUrl: string; // URL to download file from
toFile: string; // Local filesystem path to save the file to
progress?: (res: DownloadProgressCallbackResult) => void; // I need to call this with DVA
};
where progress is callback
and this is my code of the file download from DVA model:
*download({payload}, {call, put}) {
const {url} = payload;
const filePath = RNFS.CachesDirectoryPath + '/test.pdf';
const download = RNFS.downloadFile({
fromUrl: url,
toFile: filePath,
progress // <-- How do I call the progress callback here with DVA ?
});
yield call(download.promise);
}
*download({ payload }, { call, put }) {
const { url } = payload;
const filePath = RNFS.CachesDirectoryPath + '/test.pdf';
function* progress() {
// yield put({ type: 'xxx' })
}
const download = RNFS.downloadFile({
fromUrl: url,
toFile: filePath,
progress, // <-- How do I call the progress callback here with DVA ?
});
yield call(download.promise);
},
or
const eventTarget = (() => {
let handle;
const off = () => (handle = undefined);
return {
on(fn) {
handle = fn;
return off;
},
off,
trigger(e) {
if (handle) {
handle(e);
}
},
};
})();
export default {
subscriptions: {
setup({ dispatch }) {
return eventTarget.on(dispatch);
},
},
effects: {
// eslint-disable-next-line no-unused-vars
*download({ payload }, { call, put }) {
const { url } = payload;
const filePath = RNFS.CachesDirectoryPath + '/test.pdf';
const download = RNFS.downloadFile({
fromUrl: url,
toFile: filePath,
progress: () => {
eventTarget.trigger({ type: 'xxx' });
}, // <-- How do I call the progress callback here with DVA ?
});
yield call(download.promise);
},
},
};
@xiaosongxiaosong thanks for reply and solutions!
The second case looks interesting!
I've resolved that with saga channel. It works even with multi files download.
I leave my solution below, maybe it will help someone.
import {channel} from 'redux-saga';
const downloadFileChannel = channel();
export default {
effects: {
*download({ payload }, { call, put }) {
const { url } = payload;
const filePath = RNFS.CachesDirectoryPath + '/test.pdf';
const download = RNFS.downloadFile({
fromUrl: url,
toFile: filePath,
progress: (progress) => downloadFileChannel.put({type: 'S_PROGRESS', payload: {progress}})
});
yield call(download.promise);
},
},
//Progress watcher.
watch: [
function* watch({take, call, put}) {
while (true) {
const action = yield take(downloadFileChannel);
const {progress} = action.payload;
const p = progress.bytesWritten / progress.contentLength;
//yield put({type: 'xxx'}) // Update your state or do something;
}
},
{type: 'watcher'},
],
}
Most helpful comment
@xiaosongxiaosong thanks for reply and solutions!
The second case looks interesting!
I've resolved that with saga channel. It works even with multi files download.
I leave my solution below, maybe it will help someone.