add server rendering of loaded compares and clean up saving of compares, switch to using isomorphic fetch (and save much compiled size)
This commit is contained in:
parent
0a3a37e64e
commit
6bb76ccd17
3
.gitignore
vendored
3
.gitignore
vendored
@ -7,3 +7,6 @@ data/*
|
||||
|
||||
browser-bundle.js.map
|
||||
npm-debug.log.*
|
||||
|
||||
stats.json
|
||||
stats.analyzed.txt
|
||||
|
21781
dist/browser-bundle.js
vendored
21781
dist/browser-bundle.js
vendored
File diff suppressed because one or more lines are too long
BIN
dist/themes/default/assets/fonts/icons.woff2
vendored
Normal file
BIN
dist/themes/default/assets/fonts/icons.woff2
vendored
Normal file
Binary file not shown.
@ -4,7 +4,7 @@
|
||||
"description": "",
|
||||
"main": "src/server/babel.index.js",
|
||||
"scripts": {
|
||||
"copy-css": "copyfiles -f ./node_modules/semantic-ui-css/semantic.min.css ./dist",
|
||||
"copy-css": "cpy --parents --cwd=./node_modules/semantic-ui-css semantic.min.css themes/default/assets/fonts/icons.woff2 ../../dist",
|
||||
"build": "npm run copy-css && webpack --colors",
|
||||
"start": "npm run copy-css && webpack --progress --colors --watch",
|
||||
"serve": "node src/server/babel.index.js",
|
||||
@ -20,15 +20,15 @@
|
||||
"body-parser": "^1.15.2",
|
||||
"diff": "^3.0.1",
|
||||
"express": "^4.14.0",
|
||||
"isomorphic-fetch": "^2.2.1",
|
||||
"jsonfile": "^2.4.0",
|
||||
"markdown-it": "^5.1.0",
|
||||
"markdown-to-jsx": "^4.0.3",
|
||||
"react": "^0.14.5",
|
||||
"react-dom": "^0.14.5",
|
||||
"react-redux": "^4.4.6",
|
||||
"react-router": "^1.0.0",
|
||||
"react-router": "~3.0.0",
|
||||
"redux": "^3.5.1",
|
||||
"redux-router": "^1.0.0-beta5",
|
||||
"redux-thunk": "^2.1.0",
|
||||
"request": "^2.79.0",
|
||||
"request-promise-native": "^1.0.3",
|
||||
|
@ -5,8 +5,8 @@ import * as Redux from 'redux'
|
||||
|
||||
import {Provider} from 'react-redux'
|
||||
|
||||
import createBrowserHistory from 'history/lib/createBrowserHistory'
|
||||
import {Router, Route, IndexRoute, Redirect } from 'react-router'
|
||||
//import createBrowserHistory from 'history/lib/createBrowserHistory'
|
||||
import {Router, Route, IndexRoute, Redirect, browserHistory } from 'react-router'
|
||||
|
||||
import thunk from 'redux-thunk'
|
||||
|
||||
@ -38,8 +38,11 @@ const store = Redux.createStore(
|
||||
Redux.applyMiddleware(...middlewares)
|
||||
)
|
||||
|
||||
console.log(store)
|
||||
//this way of reading local input isn't working:
|
||||
// it's just overriding what comes from the server
|
||||
// and it's not respecting the comparison that is loaded from the server
|
||||
|
||||
/*
|
||||
const localInput = localStore.get('dubdiff')
|
||||
if (localInput.input) {
|
||||
//dispatch localStore data to store
|
||||
@ -47,6 +50,7 @@ if (localInput.input) {
|
||||
store.dispatch(Actions.updateFinalInput(localInput.input.final))
|
||||
//should this be done after the first render?
|
||||
}
|
||||
*/
|
||||
|
||||
//save the state whenever the state changes
|
||||
function saveState() {
|
||||
@ -60,7 +64,7 @@ store.subscribe(saveState)
|
||||
function render() {
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<Router history={createBrowserHistory()}>
|
||||
<Router history={browserHistory}>
|
||||
{routes}
|
||||
</Router>
|
||||
</Provider>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import requestPromise from 'request-promise-native'
|
||||
import fetch from 'isomorphic-fetch'
|
||||
import uuid from 'uuid/v4'
|
||||
|
||||
export const updateOriginalInput = (text) =>
|
||||
@ -24,43 +24,82 @@ export const clearInput = () =>
|
||||
dispatch({ type: 'SAVE_STATUS_EMPTY'})
|
||||
}
|
||||
|
||||
export const updateOriginalCompare = (text) => ({ type: 'UPDATE_ORIGINAL_COMPARE', data:text})
|
||||
export const updateFinalCompare = (text) => ({ type: 'UPDATE_FINAL_COMPARE', data:text})
|
||||
export const clearCompare = () => ({ type: 'CLEAR_COMPARE'})
|
||||
export const setPlaintextFormat = () => ({ type: 'SET_PLAINTEXT_FORMAT'})
|
||||
export const setMarkdownFormat = () => ({ type: 'SET_MARKDOWN_FORMAT'})
|
||||
export const showOriginal = () => ({ type: 'SHOW_ORIGINAL'})
|
||||
export const showFinal = () => ({ type: 'SHOW_FINAL'})
|
||||
export const showDifference = () => ({ type: 'SHOW_DIFFERENCE'})
|
||||
|
||||
|
||||
//saves the current input fields to the server
|
||||
//creates and returns a new id for the
|
||||
export const save = () =>
|
||||
(dispatch, getState) => {
|
||||
|
||||
console.log("!!! SAVING")
|
||||
|
||||
//generate an id
|
||||
const id = uuid()
|
||||
dispatch( {type: 'SAVE_STATUS_ASSIGN_ID', id})
|
||||
|
||||
//set waiting state
|
||||
dispatch( {type: 'SAVE_STATUS_WAITING'})
|
||||
|
||||
const reqOptions = {
|
||||
const endpointUri = `/api/compare/${id}`
|
||||
const fetchOptions = {
|
||||
method: 'POST',
|
||||
uri: `${location.origin}/api/compare/${id}`,
|
||||
body: {
|
||||
body: JSON.stringify({
|
||||
a: getState().input.original,
|
||||
b: getState().input.final
|
||||
}),
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
json: true
|
||||
}
|
||||
|
||||
|
||||
//dispatch post request
|
||||
requestPromise(reqOptions)
|
||||
.then(returnBodyJson => {
|
||||
fetch(endpointUri, fetchOptions)
|
||||
.then(response => {
|
||||
dispatch( {type: 'SAVE_STATUS_SAVED'})
|
||||
})
|
||||
.catch(error => {
|
||||
dispatch( {type: 'SAVE_STATUS_FAILED', error})
|
||||
})
|
||||
|
||||
//return the id after the request has been sent
|
||||
return id;
|
||||
}
|
||||
|
||||
/*
|
||||
const load = (id) =>
|
||||
(dispatch, getState) => {
|
||||
|
||||
//set waiting state
|
||||
dispatch( {type: 'SAVE_STATUS_WAITING'})
|
||||
|
||||
const endpointUri = `/api/compare/${id}`
|
||||
const fetchOptions = {
|
||||
method: 'GET'
|
||||
}
|
||||
|
||||
|
||||
//dispatch post request
|
||||
fetch(endpointUri, fetchOptions)
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch( {type: 'UPDATE_ORIGINAL_INPUT', data:json.a})
|
||||
dispatch( {type: 'UPDATE_FINAL_INPUT', data:json.b})
|
||||
dispatch( {type: 'LOAD_STATUS_LOADED'})
|
||||
})
|
||||
.catch(error => {
|
||||
dispatch( {type: 'LOAD_STATUS_FAILED', error})
|
||||
})
|
||||
|
||||
//return the id after the request has been sent
|
||||
return id;
|
||||
|
||||
}
|
||||
|
||||
export const loadIfNeeded = (id) =>
|
||||
(dispatch, getState) => {
|
||||
if
|
||||
}
|
||||
*/
|
@ -18,19 +18,24 @@ const mapStateToProps = (state) => ({
|
||||
isShowOriginal: Selectors.isShowOriginal(state),
|
||||
isShowFinal: Selectors.isShowFinal(state),
|
||||
isShowDifference: Selectors.isShowDifference(state),
|
||||
compare: state.compare,
|
||||
safeInput: Selectors.safeInput(state),
|
||||
diff: Selectors.diff(state)
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
//loadIfNeeded: (id) => dispatch(Actions.loadIfNeeded())
|
||||
})
|
||||
|
||||
|
||||
|
||||
class Compare extends React.Component {
|
||||
/*
|
||||
componentDidMount() {
|
||||
this.props.loadIfNeeded(this.props.routeParams.compareId)
|
||||
}
|
||||
*/
|
||||
|
||||
render() {
|
||||
console.log({isMarkdownFormat: this.props.isMarkdownFormat, isShowDifference: this.props.isShowDifference})
|
||||
return (
|
||||
<div>
|
||||
<Header/>
|
||||
@ -49,11 +54,11 @@ class Compare extends React.Component {
|
||||
<ShowMarkdown diff={this.props.diff}>{this.props.diff}</ShowMarkdown>:
|
||||
(!this.props.isMarkdownFormat && !this.props.isShowDifference) ?
|
||||
<ShowPlaintext
|
||||
text={this.props.isShowOriginal? this.props.compare.original: this.props.compare.final}
|
||||
text={this.props.isShowOriginal? this.props.safeInput.original: this.props.safeInput.final}
|
||||
/> :
|
||||
(this.props.isMarkdownFormat && !this.props.isShowDifference) ?
|
||||
<ShowMarkdown
|
||||
text={this.props.isShowOriginal? this.props.compare.original: this.props.compare.final}
|
||||
text={this.props.isShowOriginal? this.props.safeInput.original: this.props.safeInput.final}
|
||||
/> :
|
||||
null
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ const mapStateToProps = (state) => ({
|
||||
isShowOriginal: Selectors.isShowOriginal(state),
|
||||
isShowFinal: Selectors.isShowFinal(state),
|
||||
isShowDifference: Selectors.isShowDifference(state),
|
||||
compare: state.compare
|
||||
})
|
||||
|
||||
|
||||
@ -22,17 +21,14 @@ const mapDispatchToProps = dispatch => ({
|
||||
onShowOriginal: () => dispatch(Actions.showOriginal()),
|
||||
onShowFinal: () => dispatch(Actions.showFinal()),
|
||||
onShowDifference: () => dispatch(Actions.showDifference()),
|
||||
onEdit: (compare) => {
|
||||
dispatch(Actions.updateOriginalInput(compare.original))
|
||||
dispatch(Actions.updateFinalInput(compare.final))
|
||||
dispatch(Actions.clearCompare())
|
||||
onEdit: () => {
|
||||
}
|
||||
})
|
||||
|
||||
class CompareControls extends React.Component {
|
||||
|
||||
onClickEdit() {
|
||||
this.props.onEdit(this.props.compare)
|
||||
this.props.onEdit()
|
||||
}
|
||||
|
||||
onClickMarkdownFormat() {
|
||||
|
@ -1,10 +1,11 @@
|
||||
import React from 'react'
|
||||
import {connect} from 'react-redux'
|
||||
|
||||
import {Segment, Header} from 'semantic-ui-react'
|
||||
import {Segment, Header, Rail, Container} from 'semantic-ui-react'
|
||||
import {Link} from 'react-router'
|
||||
|
||||
import * as Actions from '../actions'
|
||||
import SaveStatus from './SaveStatus'
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
})
|
||||
@ -18,8 +19,20 @@ const mapDispatchToProps = dispatch => ({
|
||||
})
|
||||
|
||||
const SiteHeader = (props) => (
|
||||
|
||||
|
||||
<Segment basic >
|
||||
|
||||
<Segment basic padded textAlign="center" as="header" id='masthead'>
|
||||
<Link to="/"><Header onClick={props.onClear}>dubdiff</Header></Link>
|
||||
<Header><Link onClick={props.onClear} to="/">dubdiff</Link></Header>
|
||||
</Segment>
|
||||
|
||||
<Rail internal position="right">
|
||||
<Segment basic padded>
|
||||
<SaveStatus/>
|
||||
</Segment>
|
||||
</Rail>
|
||||
|
||||
</Segment>
|
||||
)
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react'
|
||||
import {connect} from 'react-redux'
|
||||
import {Link} from 'react-router'
|
||||
import {browserHistory} from 'react-router'
|
||||
|
||||
import {Button, Icon, Segment} from 'semantic-ui-react'
|
||||
|
||||
@ -10,27 +10,30 @@ import * as Selectors from '../selectors'
|
||||
const mapStateToProps = (state) => ({
|
||||
format: state.format,
|
||||
isMarkdownFormat: Selectors.isMarkdownFormat(state),
|
||||
safeInput: Selectors.safeInput(state)
|
||||
saveStatus: state.saveStatus
|
||||
})
|
||||
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
onSetPlaintextFormat: (format) => dispatch(Actions.setPlaintextFormat()),
|
||||
onSetMarkdownFormat: (format) => dispatch(Actions.setMarkdownFormat()),
|
||||
onCompare: (safeInput) => {
|
||||
dispatch(Actions.save())
|
||||
dispatch(Actions.updateOriginalCompare(safeInput.original))
|
||||
dispatch(Actions.updateFinalCompare(safeInput.final))
|
||||
|
||||
//returns an id for the record to be saved
|
||||
startSaveAsync: () => {
|
||||
return dispatch(Actions.save())
|
||||
}
|
||||
})
|
||||
|
||||
class MainControls extends React.Component {
|
||||
|
||||
onClickCompare() {
|
||||
//generate new id? (or should the id be baked into the link route?)
|
||||
//post safeInput to db
|
||||
//start saving the input to the server
|
||||
const id = this.props.startSaveAsync()
|
||||
|
||||
//we can use the id created by the save method to build a path
|
||||
const comparePath = `/${id}`
|
||||
browserHistory.replace(comparePath)
|
||||
|
||||
this.props.onCompare(this.props.safeInput)
|
||||
return false
|
||||
}
|
||||
|
||||
@ -46,7 +49,7 @@ class MainControls extends React.Component {
|
||||
return (
|
||||
<Segment.Group>
|
||||
<Segment >
|
||||
<Link to="compare"><Button fluid onClick={this.onClickCompare.bind(this)}>Compare</Button></Link>
|
||||
<Button fluid onClick={this.onClickCompare.bind(this)}>Compare</Button>
|
||||
</Segment>
|
||||
|
||||
<Segment >
|
||||
|
52
src/common/components/SaveStatus.js
Normal file
52
src/common/components/SaveStatus.js
Normal file
@ -0,0 +1,52 @@
|
||||
import React from 'react'
|
||||
import {connect} from 'react-redux'
|
||||
|
||||
import { Message, Icon, Button} from 'semantic-ui-react'
|
||||
import { browserHistory} from 'react-router'
|
||||
|
||||
import * as Actions from '../actions'
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
saveStatus: state.saveStatus
|
||||
})
|
||||
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
retrySave: () => dispatch(Actions.save())
|
||||
})
|
||||
|
||||
const onRetrySaveClick = (props) => {
|
||||
//we can use the id created by the save method to build a path
|
||||
const id = props.retrySave()
|
||||
const comparePath = `/${id}`
|
||||
browserHistory.replace(comparePath)
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
const SaveStatus = (props) => {
|
||||
if (props.saveStatus.waiting) return (
|
||||
<Message size='tiny' floating compact icon>
|
||||
<Icon name='circle notched' loading />
|
||||
<Message.Content>
|
||||
<Message.Header>Saving diff</Message.Header>
|
||||
</Message.Content>
|
||||
</Message>
|
||||
)
|
||||
else if (props.saveStatus.failed) return (
|
||||
<Message size='tiny' floating compact icon>
|
||||
<Icon name='exclamation' />
|
||||
<Message.Content>
|
||||
<Message.Header>Error saving diff</Message.Header>
|
||||
The server returned {props.saveStatus.error.message}.
|
||||
<Button onClick={()=>onRetrySaveClick(props)}>Retry</Button>
|
||||
</Message.Content>
|
||||
</Message>
|
||||
|
||||
)
|
||||
|
||||
else return ( <div></div> )
|
||||
}
|
||||
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(SaveStatus)
|
10
src/common/constants.js
Normal file
10
src/common/constants.js
Normal file
@ -0,0 +1,10 @@
|
||||
export const Format = {
|
||||
PLAINTEXT: 'PLAINTEXT',
|
||||
MARKDOWN: 'MARKDOWN'
|
||||
}
|
||||
|
||||
export const Show = {
|
||||
ORIGINAL:'ORIGINAL',
|
||||
FINAL:'FINAL',
|
||||
DIFFERENCE:'DIFFERENCE'
|
||||
}
|
@ -14,20 +14,6 @@ export function input (state, action ) {
|
||||
}
|
||||
}
|
||||
|
||||
export function compare (state, action ) {
|
||||
switch (action.type) {
|
||||
case 'UPDATE_ORIGINAL_COMPARE':
|
||||
return Object.assign({}, state, {original:action.data})
|
||||
case 'UPDATE_FINAL_COMPARE':
|
||||
return Object.assign({}, state, {final:action.data})
|
||||
case 'CLEAR_COMPARE':
|
||||
return {original:'', final:''}
|
||||
default:
|
||||
return state || {original:'', final:''}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function format (state, action) {
|
||||
switch (action.type) {
|
||||
case 'SET_PLAINTEXT_FORMAT':
|
||||
@ -57,18 +43,30 @@ export function show (state, action) {
|
||||
export function saveStatus (state, action) {
|
||||
switch (action.type) {
|
||||
case 'SAVE_STATUS_DIRTY':
|
||||
return {dirty:true, id:null}
|
||||
return {dirty: true}
|
||||
case 'SAVE_STATUS_EMPTY':
|
||||
return {dirty:false, id:null}
|
||||
return {dirty: false, empty: true}
|
||||
case 'SAVE_STATUS_SAVED':
|
||||
return Object.assign({}, state, {waiting: false, dirty:false, failed: false, error:null})
|
||||
return {dirty: false, saved: true}
|
||||
case 'SAVE_STATUS_FAILED' :
|
||||
return Object.assign({}, state, {waiting: false, failed: true, error: action.error})
|
||||
case 'SAVE_STATUS_WAITING' :
|
||||
return Object.assign({}, state, {waiting: true, failed: false, error: null })
|
||||
case 'SAVE_STATUS_ASSIGN_ID':
|
||||
return Object.assign({}, state, {id: action.id})
|
||||
return Object.assign({}, state, {waiting: true, failed: false, error: null})
|
||||
default:
|
||||
return state || {empty: true, dirty:false, id:null}
|
||||
return state || {empty: true, dirty:false}
|
||||
}
|
||||
}
|
||||
/*
|
||||
export function loadStatus (state, action) {
|
||||
switch (action.type) {
|
||||
case 'LOAD_STATUS_WAITING':
|
||||
return {waiting: true}
|
||||
case 'LOAD_STATUS_FAILED':
|
||||
return {failed: true, error: action.error }
|
||||
case 'LOAD_STATUS_LOADED':
|
||||
return {loaded: true}
|
||||
default:
|
||||
return state || {waiting: false}
|
||||
}
|
||||
}
|
||||
*/
|
@ -13,7 +13,6 @@ import * as Dubdiff from './util/dubdiff'
|
||||
const input = (state) => state.input
|
||||
const format = (state) => state.format
|
||||
const show = (state) => state.show
|
||||
const compare = (state) => state.compare
|
||||
|
||||
export const safeInput = createSelector(
|
||||
[input],
|
||||
@ -43,9 +42,9 @@ export const isShowDifference= isShow(Show.DIFFERENCE)
|
||||
|
||||
|
||||
export const diff = createSelector(
|
||||
[format, compare],
|
||||
(format, compare) => {
|
||||
return Dubdiff.plaintextDiff(compare.original, compare.final)
|
||||
[format, safeInput],
|
||||
(format, safeInput) => {
|
||||
return Dubdiff.plaintextDiff(safeInput.original, safeInput.final)
|
||||
/*
|
||||
let diff = JsDiff.diffWords (input.original.replace(/ /g, ' '), input.final.replace(/ /g, ' '))
|
||||
return diff.map(({added, removed, value})=>({added, removed, value:value.replace(/ /g, ' ')})).map(part => (
|
||||
|
@ -31,7 +31,6 @@ function createComparisonWithId(req, res) {
|
||||
const id = req.params.id
|
||||
const {a, b} = req.body
|
||||
|
||||
|
||||
return writeRecord(res, id, {a, b, id})
|
||||
}
|
||||
|
||||
@ -82,12 +81,12 @@ function writeRecord(res, id, data) {
|
||||
module.exports = router
|
||||
|
||||
function handleError(res, err) {
|
||||
console.log(err);
|
||||
return res.send(500, err);
|
||||
console.log(err)
|
||||
return res.send(500, err)
|
||||
}
|
||||
|
||||
|
||||
// returns a filename for the given comparison
|
||||
function fnData (id) {
|
||||
return "./data/" + "id-" + id + ".json";
|
||||
return `./data/${id}.json`
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ import path from 'path'
|
||||
import bodyParser from 'body-parser'
|
||||
import * as Redux from 'redux'
|
||||
|
||||
import fetch from 'isomorphic-fetch'
|
||||
|
||||
import comparisonRouter from './comparison'
|
||||
|
||||
|
||||
@ -11,6 +13,8 @@ import * as actions from '../common/actions'
|
||||
|
||||
import render from './render'
|
||||
|
||||
const PORT = 8080
|
||||
|
||||
const app = express()
|
||||
|
||||
//serve the dist static files at /dist
|
||||
@ -24,27 +28,40 @@ app.use('/api/compare', comparisonRouter);
|
||||
|
||||
//the following routes are for server-side rendering of the app
|
||||
|
||||
//eventually, we should render the comparison directly from the server
|
||||
/*
|
||||
//we should render the comparison directly from the server
|
||||
|
||||
//this is garbage, we should use a robust method for loading comparisons, parallel to how saving works
|
||||
//comparisons should be loaded isomorphically
|
||||
app.route('/:comparisonId')
|
||||
.get((req, res) => {
|
||||
|
||||
const store = createSessionStore()
|
||||
...
|
||||
|
||||
//fetch the comparison
|
||||
fetchComparison(req.params.comparisonId)
|
||||
.then( ({a,b}) => {
|
||||
store.dispatch({type: 'UPDATE_ORIGINAL_INPUT', data: a})
|
||||
store.dispatch({type: 'UPDATE_FINAL_INPUT', data: b})
|
||||
render(store, req, res)
|
||||
})
|
||||
.catch( error => {
|
||||
//... what to do here?
|
||||
console.log(`Error fetching comparison with id ${req.params.comparisonId}`, error)
|
||||
})
|
||||
|
||||
})
|
||||
app.route('/'). ...
|
||||
*/
|
||||
app.route('/')
|
||||
.get((req, res) => {
|
||||
render(createSessionStore(), req, res)
|
||||
})
|
||||
|
||||
|
||||
//but for now, let's just render the app and let it fetch comparison data
|
||||
app.use((req, res) => render(createSessionStore(), req, res))
|
||||
|
||||
app.listen(8080, function () {
|
||||
app.listen(PORT, function () {
|
||||
console.log('Server listening on port 8080.')
|
||||
})
|
||||
|
||||
|
||||
//this is pretty much redundant at this point
|
||||
//creates the session store
|
||||
function createSessionStore() {
|
||||
//create the redux store
|
||||
return Redux.createStore(
|
||||
@ -53,7 +70,16 @@ function createSessionStore() {
|
||||
}
|
||||
|
||||
|
||||
function fetchComparison(id) {
|
||||
const endpointUri = `http://localhost:${PORT}/api/compare/${id}`
|
||||
const fetchOptions = {
|
||||
method: 'GET'
|
||||
}
|
||||
|
||||
//dispatch post request
|
||||
return fetch(endpointUri, fetchOptions)
|
||||
.then(response => response.json())
|
||||
}
|
||||
|
||||
|
||||
//router.get('/', controller.index);
|
||||
|
@ -1,18 +1,17 @@
|
||||
import React from 'react'
|
||||
import { renderToString } from 'react-dom/server'
|
||||
import { Provider } from 'react-redux'
|
||||
import { match, RoutingContext } from 'react-router'
|
||||
import { match, RouterContext } from 'react-router'
|
||||
|
||||
import routes from '../common/routes.js'
|
||||
|
||||
|
||||
export default function render(store, req, res) {
|
||||
console.log(store.getState())
|
||||
|
||||
// Send the rendered page back to the client
|
||||
match({ routes, location: req.url }, (error, redirectLocation, renderProps) => {
|
||||
if (error) {
|
||||
res.status(500).send(renderError('Routing Error', error.message))
|
||||
console.log(error)
|
||||
res.status(500).send(renderError('Routing Error:', error.message))
|
||||
} else if (redirectLocation) {
|
||||
res.redirect(302, redirectLocation.pathname + redirectLocation.search)
|
||||
} else if (renderProps) {
|
||||
@ -20,7 +19,7 @@ export default function render(store, req, res) {
|
||||
try {
|
||||
const html = renderToString(
|
||||
<Provider store={store}>
|
||||
<RoutingContext {...renderProps} />
|
||||
<RouterContext {...renderProps} />
|
||||
</Provider>
|
||||
)
|
||||
|
||||
@ -30,6 +29,7 @@ export default function render(store, req, res) {
|
||||
res.status(200).send(appTemplate(html, initialState))
|
||||
}
|
||||
catch(ex) {
|
||||
console.log("Render Exception:",ex)
|
||||
res.status(500).send(errorTemplate('Render Exception', ex.message, ex))
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user