Skip to content
Snippets Groups Projects
Commit 6985b611 authored by Erkki Heino's avatar Erkki Heino
Browse files

Use redux-observable

parent 6aba4f55
No related branches found
No related tags found
No related merge requests found
[*]
indent_style = space
indent_size = 2
...@@ -7,7 +7,8 @@ module.exports = { ...@@ -7,7 +7,8 @@ module.exports = {
], ],
"quotes": [ "quotes": [
2, 2,
"single" "single",
{ "allowTemplateLiterals": true }
], ],
"linebreak-style": [ "linebreak-style": [
2, 2,
...@@ -19,7 +20,7 @@ module.exports = { ...@@ -19,7 +20,7 @@ module.exports = {
], ],
//'no-console': 'off', //'no-console': 'off',
"react/jsx-uses-vars": ["error"], "react/jsx-uses-vars": ["error"],
"space-infix-ops": ["error", {"int32Hint": true}] "space-infix-ops": ["error", {"int32Hint": true}],
}, },
"env": { "env": {
"es6": true, "es6": true,
......
node_modules node_modules
*.swp
This diff is collapsed.
export const FETCH_RESULTS = 'FETCH_RESULTS';
export const UPDATE_QUERY = 'UPDATE_QUERY';
export const UPDATE_DATASETS = 'UPDATE_DATASETS';
export const UPDATE_RESULTS = 'UPDATE_RESULTS';
export const CLEAR_RESULTS = 'CLEAR_RESULTS';
export const START_SPINNER = 'START_SPINNER';
export const updateQuery = (query) => ({ export const updateQuery = (query) => ({
type: 'UPDATE_QUERY', type: UPDATE_QUERY,
query query
}); });
export const fetchResults = () => ({ export const fetchResults = () => ({
type: 'FETCH_RESULTS', type: FETCH_RESULTS,
meta: {
debounce: {
time: 750
}
}
}); });
export const updateDatasets = (datasets) => ({ export const updateDatasets = (datasets) => ({
type: 'UPDATE_DATASETS', type: UPDATE_DATASETS,
datasets datasets
}); });
export const startSpinner = () => ({ export const startSpinner = () => ({
type: 'START_SPINNER', type: START_SPINNER,
}); });
export const updateResults = (results) => ({ export const updateResults = (results) => ({
type: 'UPDATE_RESULTS', type: UPDATE_RESULTS,
results results
}); });
export const clearResults = () => ({ export const clearResults = () => ({
type: 'CLEAR_RESULTS', type: CLEAR_RESULTS,
}); });
import 'rxjs';
import _ from 'lodash';
import { ajax } from 'rxjs/observable/dom/ajax';
import { combineEpics } from 'redux-observable';
import { updateResults, FETCH_RESULTS } from '../actions';
const getSuggestionsEpic = (action$, store) => {
const searchUrl = 'http://localhost:3000/search';
return action$.ofType(FETCH_RESULTS)
.debounceTime(500)
.switchMap(() => {
const { query, datasets } = store.getState().search;
const dsParams = _.map(datasets, ds => `dataset=${ds}`).join('&');
const requestUrl = `${searchUrl}?q=${query}&${dsParams}`;
return ajax.getJSON(requestUrl)
.map(response => updateResults(response));
});
};
const rootEpic = combineEpics(getSuggestionsEpic);
export default rootEpic;
import React from 'react'; import React from 'react';
import { render } from 'react-dom'; import { render } from 'react-dom';
import { createStore, applyMiddleware } from 'redux'; import { createStore, applyMiddleware } from 'redux';
import { createEpicMiddleware } from 'redux-observable';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import thunk from 'redux-thunk';
import reducer from './reducers'; import reducer from './reducers';
// import { logger, crashReporter } from './middleware/crashReporter'; import rootEpic from './epics';
import hiplaApiMiddleware from './middleware/hiplaApiMiddleware';
import createDebounce from 'redux-debounced';
import App from './components/App'; import App from './components/App';
const store = createStore( const store = createStore(
reducer, reducer,
// applyMiddleware() tells createStore() how to handle middleware // applyMiddleware() tells createStore() how to handle middleware
applyMiddleware(thunk, createDebounce(), hiplaApiMiddleware()) applyMiddleware(createEpicMiddleware(rootEpic))
); );
render( render(
......
import { startSpinner, updateResults } from '../actions';
import request from 'superagent';
const hiplaApiMiddleware = () => {
const searchUrl = 'http://localhost:3000/search';
const getResults = (store) => {
const { query, datasets } = store.getState().search;
if (query.length < 3) {
return store.dispatch(updateResults([]));
}
console.log('query:', query);
console.log('datasets:', datasets);
return request(searchUrl)
.query({ q: query})
.query({ dataset: datasets})
.then(response => {
if (!response.ok) {
return Promise.reject(response);
}
return store.dispatch(updateResults(response.body));
});
};
// A Redux middleware
return store => next => action => {
switch(action.type) {
case 'FETCH_RESULTS':
console.log('action: FETCH_RESULTS');
store.dispatch(startSpinner);
next(action);
return getResults(store);
default:
return next(action);
}
};
};
export default hiplaApiMiddleware;
import { UPDATE_QUERY, FETCH_RESULTS, UPDATE_DATASETS, UPDATE_RESULTS, CLEAR_RESULTS } from '../actions';
export const INITIAL_STATE = { export const INITIAL_STATE = {
query: '', query: '',
datasets: ['warsa_karelian_places'], datasets: ['warsa_karelian_places'],
...@@ -5,15 +7,20 @@ export const INITIAL_STATE = { ...@@ -5,15 +7,20 @@ export const INITIAL_STATE = {
}; };
const search = (state = INITIAL_STATE, action) => { const search = (state = INITIAL_STATE, action) => {
// console.log(state, action);
switch (action.type) { switch (action.type) {
case 'UPDATE_QUERY': case UPDATE_QUERY:
return { ...state, query: action.query || '' }; return { ...state, query: action.query || '' };
case 'UPDATE_DATASETS': case FETCH_RESULTS:
return { ...state, isFetchingResults: true };
case UPDATE_DATASETS:
return { ...state, datasets: action.datasets || [] }; return { ...state, datasets: action.datasets || [] };
case 'UPDATE_RESULTS': case UPDATE_RESULTS:
return { ...state, suggestions: action.results || [] }; return {
case 'CLEAR_RESULTS': ...state,
suggestions: action.results || [],
isFetchingResults: false
};
case CLEAR_RESULTS:
return { ...state, suggestions: [] }; return { ...state, suggestions: [] };
default: default:
return state; return state;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment