Refactoring to improve readability, compatibility with saga and comments

This commit is contained in:
Vesa Luusua 2017-02-07 13:13:08 +02:00
parent f508886d9f
commit bc2baaf3b5
8 changed files with 30 additions and 41 deletions

View file

@ -29,14 +29,7 @@ exports.fetchListings = () => {
const randomTime = Math.random() * 2000;
const fakeResponseTime = 1000 + randomTime;
const fakeFetch = new Promise((resolve, reject) => {
setTimeout(
() => {
resolve({ response: fakeListings });
// or reject({ error: new Error('FetchListings errored') );
},
fakeResponseTime,
);
return new Promise((resolve, reject) => {
setTimeout(() => resolve(fakeListings), fakeResponseTime);
});
return fakeFetch;
};

View file

@ -80,8 +80,8 @@ function fetchInitialState(requestUrl) {
// We filter all the components form matched routes that have `loadData`
const initialFetches = _
.chain(matchedRoutes)
.filter(r => r.loadData && r.loadData.fetchData)
.map(r => sagaEffects.fork(r.loadData.fetchData, sdk))
.filter(r => r.loadData)
.map(r => sagaEffects.fork(r.loadData, sdk))
.value();
// We need to combine different onload sagas under one yield
@ -100,8 +100,8 @@ function fetchInitialState(requestUrl) {
.catch(e => {
reject(e);
});
// Close temporary store (which was used only for fetching initial store state)
store.close();
// Close temporary store's saga middleware (which was used only for fetching initial store state)
store.closeSagaMiddleware();
});
return fetchPromise;
}

View file

@ -4,7 +4,7 @@
* https://github.com/erikras/ducks-modular-redux
*/
import { unionWith, isEqual } from 'lodash';
import { call, take, put } from 'redux-saga/effects';
import { call, put, takeEvery } from 'redux-saga/effects';
import { createRequestTypes } from '../../util/sagaHelpers';
// ================ Action types ================ //
@ -65,10 +65,10 @@ export const loadListings = {
// ================ Worker sagas ================ //
export function* callFetchListings(sdk) {
const { response, error } = yield call(sdk.fetchListings);
if (response) {
try {
const response = yield call(sdk.fetchListings);
yield put(loadListings.success(response));
} else {
} catch(error) {
yield put(loadListings.failure(error));
}
}
@ -77,8 +77,5 @@ export function* callFetchListings(sdk) {
export function* watchLoadListings(sdk) {
// eslint-disable-next-line no-constant-condition
while (true) {
yield take(LOAD_LISTINGS.REQUEST);
yield call(callFetchListings, sdk);
}
yield takeEvery(LOAD_LISTINGS.REQUEST, callFetchListings, sdk);
}

View file

@ -34,10 +34,10 @@ export class SearchPageComponent extends Component {
const filtersClassName = classNames(css.filters, {
[css.open]: selectedTab === 'filters',
});
const listingsClassName = classNames(css.filters, {
const listingsClassName = classNames(css.listings, {
[css.open]: selectedTab === 'listings',
});
const mapClassName = classNames(css.filters, {
const mapClassName = classNames(css.map, {
[css.open]: selectedTab === 'map',
});
@ -63,7 +63,7 @@ export class SearchPageComponent extends Component {
}
}
SearchPageComponent.loadData = { fetchData: callFetchListings, fetchDataAction: loadListings };
SearchPageComponent.loadData = callFetchListings;
SearchPageComponent.defaultProps = { SearchPage: {}, tab: 'listings' };

View file

@ -33,4 +33,7 @@ if (typeof window !== 'undefined') {
// Export the function for server side rendering.
export default renderApp;
// exporting matchPathname and configureStore for server side rendering.
// matchPathname helps to figure out which route is called and if it has preloading needs
// configureStore is used for creating initial store state for Redux after preloading
export { matchPathname, configureStore };

View file

@ -281,27 +281,29 @@ const pathByRouteName = (nameToFind, routes, params = {}) =>
* matchRoutesToLocation helps to figure out which routes are related to given location.
*/
const matchRoutesToLocation = (routes, location, matchedRoutes = [], params = {}) => {
const parameters = { ...params };
let parameters = { ...params };
let matched = [...matchedRoutes];
routes.forEach(route => {
const { exactly = false } = route;
const match = !route.pattern ? true : matchPattern(route.pattern, location, exactly);
if (match) {
matchedRoutes.push(route);
matched.push(route);
if (match.params) {
Object.keys(match.params).forEach(key => {
parameters[key] = match.params[key];
});
parameters = { ...parameters, ...match.params };
}
}
if (route.routes) {
matchRoutesToLocation(route.routes, location, matchedRoutes, parameters);
const { matchedRoutes: subRouteMatches, params: subRouteParams } = matchRoutesToLocation(route.routes, location, matched, parameters);
matched = matched.concat(subRouteMatches);
parameters = { ...parameters, ...subRouteParams };
}
});
return { matchedRoutes, params: parameters };
return { matchedRoutes: matched, params: parameters };
};
const matchPathnameCreator = routes =>

View file

@ -23,7 +23,7 @@ export default function configureStore(initialState = {}) {
const store = createStore(createReducer(), initialState, enhancer);
store.runSaga = sagaMiddleware.run;
store.close = () => store.dispatch(END);
store.closeSagaMiddleware = () => store.dispatch(END);
return store;
}

View file

@ -30,16 +30,10 @@ const fakeSDK = {
const randomTime = Math.random() * 2000;
const fakeResponseTime = 1000 + randomTime;
const fakeFetch = new Promise((resolve, reject) => {
setTimeout(
() => {
resolve({ response: fakeListings });
// or reject({ error: new Error('FetchListings errored') );
},
fakeResponseTime,
);
return new Promise((resolve, reject) => {
setTimeout(() => resolve(fakeListings), fakeResponseTime);
});
return fakeFetch;
},
};
export default fakeSDK;