Skip to content

Commit ef207b1

Browse files
committedDec 10, 2016
added movies example
1 parent 479da07 commit ef207b1

File tree

14 files changed

+161
-19
lines changed

14 files changed

+161
-19
lines changed
 

‎client/actions/movies.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
export const MOVIES_REQUEST = 'MOVIES_REQUEST';
2+
export const MOVIES_SUCCESS = 'MOVIES_SUCCESS';
3+
export const MOVIES_FAILURE = 'MOVIES_FAILURE';
4+
5+
export function moviesRequest() {
6+
return {
7+
type: MOVIES_REQUEST,
8+
};
9+
}
10+
11+
export function moviesSuccess(movies) {
12+
return {
13+
type: MOVIES_SUCCESS,
14+
payload: movies,
15+
};
16+
}
17+
18+
export function moviesFailure(message) {
19+
return {
20+
type: MOVIES_FAILURE,
21+
error: true,
22+
payload: new Error(message),
23+
};
24+
}

‎client/app.jsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import React from 'react';
33
import { Provider } from 'react-redux';
44
import { BrowserRouter, ServerRouter, Match } from 'react-router';
55

6-
import { Layout, Hello } from 'components';
6+
import { Layout } from 'components';
7+
import { Movies } from 'containers';
78

89
type Props = {
910
context?: Object,
@@ -21,7 +22,7 @@ class Blrplt extends React.Component { // eslint-disable-line react/prefer-state
2122
// Declare your routes here.
2223
const layout = (
2324
<Layout>
24-
<Match pattern="*" component={Hello} />
25+
<Match pattern="*" component={Movies} />
2526
</Layout>
2627
);
2728

‎client/components/Hello.jsx

-7
This file was deleted.

‎client/components/index.js

-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
import Hello from './Hello';
21
import Html from './Html';
32
import Layout from './Layout';
43

54
export {
6-
Hello,
75
Html,
86
Layout,
97
};

‎client/containers/Movies.jsx

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { connect } from 'react-redux';
2+
3+
import { moviesRequest } from '../actions/movies';
4+
5+
type Props = {
6+
moviesRequest: Function,
7+
movies: Array<Object>,
8+
loading: boolean,
9+
}
10+
11+
@connect(
12+
state => ({
13+
movies: state.movies.movies,
14+
loading: state.movies.loading,
15+
}),
16+
{ moviesRequest }
17+
)
18+
class Movies extends React.Component {
19+
constructor(props: Props) {
20+
super(props);
21+
22+
if (!props.movies.length) {
23+
props.moviesRequest();
24+
}
25+
}
26+
27+
render() {
28+
return (
29+
<div>
30+
<h2>Movies</h2>
31+
{this.props.loading ? (
32+
<p>Loading...</p>
33+
) : (
34+
<ul>
35+
{this.props.movies.map((movie, i) => (
36+
<li key={i}>{movie.title} ({movie.releaseYear})</li>
37+
))}
38+
</ul>
39+
)}
40+
</div>
41+
);
42+
}
43+
}
44+
45+
export default Movies;

‎client/containers/index.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import Movies from './Movies';
2+
3+
export {
4+
Movies,
5+
};

‎client/helpers/handleRequest.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import qs from 'qs';
2+
3+
async function checkStatus(response) {
4+
if (response.status >= 200 && response.status < 300) {
5+
return response;
6+
}
7+
const error = new Error(response.statusText);
8+
const json = await response.json();
9+
error.response = json;
10+
throw error;
11+
}
12+
13+
function parseJSON(response) {
14+
return response.json();
15+
}
16+
17+
export function handleRequest(url, options = {}) {
18+
if (options.query) {
19+
const query = qs.stringify(options.query);
20+
url = `${url}?${query}`;
21+
}
22+
return fetch(url, options)
23+
.then(checkStatus)
24+
.then(parseJSON);
25+
}

‎client/reducers/index.js

+3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import { combineReducers } from 'redux';
22

3+
import moviesReducer from './movies';
4+
35
export default combineReducers({
6+
movies: moviesReducer,
47
});

‎client/reducers/movies.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import * as actions from '../actions/movies';
2+
3+
const initialState = {
4+
loading: false,
5+
movies: [],
6+
};
7+
8+
export default (state = initialState, action) => {
9+
switch (action.type) {
10+
case actions.MOVIES_REQUEST: {
11+
return {
12+
...state,
13+
loading: true,
14+
};
15+
}
16+
case actions.MOVIES_SUCCESS: {
17+
return {
18+
movies: action.payload,
19+
loading: false,
20+
};
21+
}
22+
default:
23+
return state;
24+
}
25+
};

‎client/sagas/index.js

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { fork } from 'redux-saga/effects';
22

3+
import { moviesSaga } from './movies';
4+
35
export default function* root() {
46
yield [
7+
fork(moviesSaga),
58
];
69
}

‎client/sagas/movies.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { takeEvery } from 'redux-saga';
2+
import { call, put } from 'redux-saga/effects';
3+
4+
import { handleRequest } from '../helpers/handleRequest';
5+
import * as actions from '../actions/movies';
6+
7+
export function* getMovies() {
8+
try {
9+
const res = yield call(handleRequest, 'https://facebook.github.io/react-native/movies.json');
10+
yield put(actions.moviesSuccess(res.movies || []));
11+
} catch (e) {
12+
yield put(actions.moviesFailure(e.response ? e.response.message : null));
13+
}
14+
}
15+
16+
export function* moviesSaga() {
17+
yield* takeEvery(actions.MOVIES_REQUEST, getMovies);
18+
}

‎config/main.js

-4
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@ const config = {
1717
],
1818
},
1919
},
20-
21-
22-
// Deploy settings
23-
bucket: 'blrplt',
2420
apiUrl: '',
2521
// Insert CDN url here (cloudfront) to correct the path that server.js uses on lambda.
2622
cdn: '',

‎package.json

+5-4
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,11 @@
5353
"redux-saga": "^0.13.0"
5454
},
5555
"config": {
56-
"s3BucketName": "",
57-
"cloudFormationStackName": "",
58-
"region": "",
59-
"functionName": "",
56+
"tmps3BucketName": "blrplt-temp",
57+
"s3BucketName": "blrplt-test",
58+
"cloudFormationStackName": "blrplt-test",
59+
"region": "eu-west-1",
60+
"functionName": "blrplt-test",
6061
"accountId": ""
6162
},
6263
"scripts": {

‎server/server.jsx

+5
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ app.get('*', (req, res) => {
5757
/>
5858
);
5959

60+
// When first render is done and all saga's are run, render again with updated store.
6061
store.runSaga(rootSaga).done.then(() => {
6162
const markup = renderToString(rootComp);
6263
const html = renderHTML(markup, store);
@@ -71,6 +72,10 @@ app.get('*', (req, res) => {
7172
}
7273
});
7374

75+
// Do first render, starts initial actions.
76+
renderToString(rootComp);
77+
78+
// When the first render is finished, send the END action to redux-saga.
7479
store.close();
7580
});
7681

0 commit comments

Comments
 (0)
Please sign in to comment.