/
dataLoader.js
42 lines (37 loc) · 1.47 KB
/
dataLoader.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
const url = require('url');
const log = require('./log');
exports.loadData = function(requestUrl, sdk, appInfo) {
const { matchPathname, configureStore, routeConfiguration, config, fetchAppAssets } = appInfo;
const { pathname, query } = url.parse(requestUrl);
const matchedRoutes = matchPathname(pathname, routeConfiguration());
let translations = {};
const store = configureStore({}, sdk);
const dataLoadingCalls = () =>
matchedRoutes.reduce((calls, match) => {
const { route, params } = match;
if (typeof route.loadData === 'function' && !route.auth) {
calls.push(store.dispatch(route.loadData(params, query)));
}
return calls;
}, []);
// First fetch app-wide assets
// Then make loadData calls
// And return object containing preloaded state and translations
// This order supports other asset (in the future) that should be fetched before data calls.
return store
.dispatch(fetchAppAssets(config.appCdnAssets))
.then(fetchedAppAssets => {
translations = fetchedAppAssets?.translations?.data || {};
return Promise.all(dataLoadingCalls());
})
.then(() => {
return { preloadedState: store.getState(), translations };
})
.catch(e => {
log.error(e, 'server-side-data-load-failed');
// Call to loadData failed, let client handle the data loading errors.
// (It might be recoverable error like lost connection.)
// Return "empty" store.
return store.getState();
});
};