diff --git a/.gitignore b/.gitignore index d31e34c..2a95d8a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ node_modules dist lib *.log -.DS_Store \ No newline at end of file +.DS_Store +tmp.json \ No newline at end of file diff --git a/index.html b/index.html index 7da3798..92304e9 100644 --- a/index.html +++ b/index.html @@ -116,6 +116,12 @@ Redux 4: Combine Reducers +
  • + + Step 9
    + Redux 5: Service Calls +
    +
  • diff --git a/server/index.js b/server/index.js index 0a277ca..d0b8778 100644 --- a/server/index.js +++ b/server/index.js @@ -1,4 +1,5 @@ // @ts-check +const fs = require('fs'); const express = require('express'); const bodyParser = require('body-parser'); const cors = require('cors'); @@ -6,6 +7,20 @@ const app = express(); const store = { /** @type {any} */ + read() { + if (fs.existsSync('tmp.json')) { + store.todos = JSON.parse(fs.readFileSync('tmp.json').toString()); + } else { + store.todos = {}; + } + + return store.todos; + }, + + save() { + fs.writeFileSync('tmp.json', JSON.stringify(store.todos)); + }, + todos: {} }; @@ -13,24 +28,28 @@ app.use(bodyParser.json()); app.use(cors()); app.get('/todos', (req, res) => { - res.json(store.todos); + res.json(store.read()); }); app.put('/todos/:id', (req, res) => { store.todos[req.params.id] = req.body; + store.save(); res.json('ok'); }); app.post('/todos/:id', (req, res) => { store.todos[req.params.id] = req.body; + store.save(); }); app.delete('/todos/:id', (req, res) => { delete store.todos[req.params.id]; + store.save(); }); app.post('/todos', req => { store.todos = req.body; + store.save(); }); app.get('/hello', (req, res) => { diff --git a/step2-09/src/index.tsx b/step2-09/src/index.tsx index f5cf5a1..df6b847 100644 --- a/step2-09/src/index.tsx +++ b/step2-09/src/index.tsx @@ -1,30 +1,35 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { reducer } from './reducers'; -import { createStore, compose } from 'redux'; +import { applyMiddleware, createStore, compose } from 'redux'; +import thunk from 'redux-thunk'; import { Provider } from 'react-redux'; import { TodoApp } from './components/TodoApp'; -import { actions } from './actions'; import { initializeIcons } from '@uifabric/icons'; -import { Store } from './store'; +import { Store, FilterTypes } from './store'; +import * as service from './service'; /* Goop for making the Redux dev tool to work */ declare var window: any; const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; function createStoreWithDevTool(reducer, initialStore?: Store) { - return createStore(reducer, initialStore, composeEnhancers()); + return createStore(reducer, initialStore, composeEnhancers(applyMiddleware(thunk))); } -const store = createStoreWithDevTool(reducer); +(async () => { + const preloadStore = { + todos: await service.getAll(), + filter: 'all' as FilterTypes + }; -store.dispatch(actions.addTodo('hello')); -store.dispatch(actions.addTodo('world')); + const store = createStoreWithDevTool(reducer, preloadStore); -initializeIcons(); + initializeIcons(); -ReactDOM.render( - - - , - document.getElementById('app') -); + ReactDOM.render( + + + , + document.getElementById('app') + ); +})(); diff --git a/webpack.config.js b/webpack.config.js index f49ed99..ca5b598 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -72,6 +72,9 @@ module.exports = function() { devServer: { contentBase: path.resolve(__dirname), watchContentBase: true, + watchOptions: { + ignored: /tmp.json/ + }, hot: false, stats: 'errors-only', overlay: true,