Add new rx saga

This commit is contained in:
Berkeley Martinez
2016-04-24 21:54:48 -07:00
parent 96f4f3413a
commit d511be3332
24 changed files with 820 additions and 531 deletions

View File

@@ -39,17 +39,20 @@ const routingMiddleware = syncHistory(history);
const devTools = window.devToolsExtension ? window.devToolsExtension() : f => f;
const shouldRouterListenForReplays = !!window.devToolsExtension;
const clientSagaOptions = { doc: document };
const sagaOptions = {
window,
document: window.document,
location: window.location
};
createApp({
history,
serviceOptions,
initialState,
middlewares: [
routingMiddleware,
...sagas.map(saga => saga(clientSagaOptions))
],
middlewares: [ routingMiddleware ],
sagas,
sagaOptions,
reducers: { routing },
enhancers: [ devTools ]
})

View File

@@ -1,20 +1,14 @@
// () =>
// (store: Store) =>
// (next: (action: Action) => Object) =>
// errSaga(action: Action) => Object|Void
export default () => ({ dispatch }) => next => {
return function errorSaga(action) {
const result = next(action);
if (!action.error) { return result; }
console.error(action.error);
return dispatch({
export default function errorSaga(action$) {
return action$
.filter(({ error }) => !!error)
.map(({ error }) => error)
.doOnNext(error => console.error(error))
.map(() => ({
type: 'app.makeToast',
payload: {
type: 'error',
title: 'Oops, something went wrong',
message: 'Something went wrong, please try again later'
}
});
};
};
}));
}

View File

@@ -1,24 +1,16 @@
import { hardGoTo } from '../../common/app/redux/types';
const loc = typeof window !== 'undefined' ?
window.location :
{};
export default () => ({ dispatch }) => next => {
return function hardGoToSaga(action) {
const result = next(action);
if (action.type !== hardGoTo) {
return result;
}
if (!loc.pathname) {
dispatch({
type: 'app.error',
error: new Error('no location object found')
});
}
loc.pathname = action.payload || '/map';
return null;
};
};
export default function hardGoToSaga(action$, getState, { location }) {
return action$
.filter(({ type }) => type === hardGoTo)
.map(({ payload = '/map' }) => {
if (!location.pathname) {
return {
type: 'app.error',
error: new Error('no location object found')
};
}
location.pathname = payload;
return null;
});
}

View File

@@ -1,3 +1,4 @@
import store from 'store';
import {
saveForm,
clearForm,
@@ -10,60 +11,33 @@ import {
} from '../../common/app/routes/Jobs/redux/actions';
const formKey = 'newJob';
let enabled = false;
let store = typeof window !== 'undefined' ?
window.localStorage :
false;
try {
const testKey = '__testKey__';
store.setItem(testKey, testKey);
enabled = store.getItem(testKey) === testKey;
store.removeItem(testKey);
} catch (e) {
enabled = !e;
}
if (!enabled) {
console.error(new Error('No localStorage found'));
}
export default () => ({ dispatch }) => next => {
return function localStorageSaga(action) {
if (!enabled) { return next(action); }
if (action.type === saveForm) {
const form = action.payload;
try {
store.setItem(formKey, JSON.stringify(form));
next(action);
return dispatch(saveCompleted(form));
} catch (error) {
return dispatch({
type: 'app.handleError',
error
});
export default function localStorageSaga(action$) {
return action$
.filter(action => {
return action.type === saveForm ||
action.type === clearForm ||
action.type === loadSavedForm;
})
.map(action => {
if (action.type === saveForm) {
const form = action.payload;
try {
store.setItem(formKey, form);
return saveCompleted(form);
} catch (error) {
return {
type: 'app.handleError',
error
};
}
}
}
if (action.type === clearForm) {
store.removeItem(formKey);
return null;
}
if (action.type === loadSavedForm) {
const formString = store.getItem(formKey);
try {
const form = JSON.parse(formString);
return dispatch(loadSavedFormCompleted(form));
} catch (error) {
return dispatch({
type: 'app.handleError',
error
});
if (action.type === clearForm) {
store.removeItem(formKey);
return null;
}
}
return next(action);
};
};
return loadSavedFormCompleted(store.getItem(formKey));
});
}

View File

@@ -1,17 +1,10 @@
// (doc: Object) =>
// () =>
// (next: (action: Action) => Object) =>
// titleSage(action: Action) => Object|Void
export default ({ doc }) => ({ getState }) => next => {
return function titleSage(action) {
// get next state
const result = next(action);
if (action.type !== 'app.updateTitle') {
return result;
}
const state = getState();
const newTitle = state.app.title;
doc.title = newTitle;
return result;
};
};
export default function titleSage(action$, getState, { document }) {
return action$
.filter(action => action.type === 'app.updateTitle')
.map(() => {
const state = getState();
const newTitle = state.app.title;
document.title = newTitle;
return null;
});
}