Skip to content

Instantly share code, notes, and snippets.

@robinfehr
Last active March 6, 2017 13:50
import { takeEvery, takeLatest, eventChannel, channel } from 'redux-saga';
import { put, call, take, fork } from 'redux-saga/effects';
import { v4 as uuid } from 'node-uuid';
import { postData } from '@postData';
import * as actions from '../actions';
function uploadDocument(documentSrc, onProgress) {
let url = `/file/document`;
return postData(url, documentSrc, {}, onProgress);
}
function createAsyncTaskRunner(documentSrc) {
let emit;
const chan = eventChannel((emitter) => {
emit = emitter;
return () => {};
});
const promise = uploadDocument(documentSrc, (eventForProgress) => {
if (eventForProgress.loaded !== eventForProgress.total) emit('PROGRESS');
});
return [promise, chan];
}
function* watchOnProgress(chan, payload) {
while (true) {
const data = yield take(chan);
yield put(actions.denormalizeEvent(payload));
}
}
function* createDocument({ payload, meta }) {
const { name, documentSrc, meta: metaFromFrontEnd } = payload;
const commonEventId = uuid();
const payloadBasic = {
id: commonEventId,
version: 0,
aggregate: {
id: uuid(),
name: 'document'
},
context: {
name: 'contentManagement'
},
payload: {
name
}
}
};
const [promise, chan] = createAsyncTaskRunner(documentSrc);
yield fork(watchOnProgress, chan, {
...payloadBasic,
name: 'documentCreated',
optimistic: true,
payload: {
...payloadBasic.payload,
uploading: true
}
});
yield fork(executeDocumentUpload, promise, payloadBasic);
}
function* executeDocumentUpload(promise, payloadBasic) {
const req = yield call(() => promise);
const { meta: metaFromFileUpload, id } = JSON.parse(req).response;
yield put(actions.sendCommandSuccess({
...payloadBasic,
name: 'createDocument',
payload: {
...payloadBasic.payload,
meta: metaFromFileUpload
}
}));
}
export default function* listenForWorkspaceChanges() {
yield* takeEvery(actions.createDocument.getType(), createDocument);
}
function futch(method, route, body, options = {}, onProgress) {
const store = getStore();
const { user } = store ? store.getState() : {};
return new Promise((res, rej) => {
var xhr = new XMLHttpRequest();
xhr.open(method || 'get', route, true);
if (user && user.data && user.data.csrfToken) {
xhr.setRequestHeader('x-csrf-token', user.data.csrfToken);
}
for (var k in options.headers||{}) {
console.log('seting header', k);
xhr.setRequestHeader(k, options.headers[k]);
}
xhr.onload = e => res(e.target.responseText);
xhr.onerror = rej;
if (xhr.upload && onProgress)
xhr.upload.onprogress = onProgress; // event.loaded / event.total * 100 ; //event.lengthComputable
xhr.send(body);
});
}
export function postData(route, data, options = {}, onProgress) {
return futch('post', route, data, {
headers: {
'Content-Type': 'text/plain;charset=UTF-8',
...options.headers
},
...options
}, onProgress);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment