From 5517141edfb8835d023aa0c1a5a47882e06334a2 Mon Sep 17 00:00:00 2001 From: Sanjay Bhangar Date: Sat, 1 Dec 2018 21:40:41 +0530 Subject: [PATCH] add example of async API request and action --- src/actions/fetchVideos.js | 48 +++++++++++++++++++++++++++++++++++++ src/config.js | 3 +++ src/containers/Home.js | 15 ++++++++++-- src/reducers/home.js | 6 +++++ src/store/configureStore.js | 4 +++- 5 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 src/actions/fetchVideos.js diff --git a/src/actions/fetchVideos.js b/src/actions/fetchVideos.js new file mode 100644 index 0000000..3dd2ea0 --- /dev/null +++ b/src/actions/fetchVideos.js @@ -0,0 +1,48 @@ +import config from '../config'; + +function fetchVideos() { + console.log('fetchVideos called'); + return dispatch => { + console.log('inside dispatch function'); + dispatch(startLoadingVideos()); + const params = { + "keys":["editable","modified","title","source","project","topic","language","duration","id"], + "query": { + "conditions":[], + "operator":"&" + }, + "range":[0,100], + "sort": [{"key":"title","operator":"+"}] + }; + let formData = new FormData(); + formData.append('action', 'find'); + formData.append('data', JSON.stringify(params)); + fetch(config.apiUrl, { + method: 'POST', + // headers: { + // "Content-Type": "application/x-www-form-urlencoded" + // }, + body: formData + }) + .then(response => response.json()) + .then(json => { + dispatch(receiveVideos(json.data.items)); + }); + + } +} + +function startLoadingVideos() { + return { + type: 'START_LOADING_VIDEOS' + } +} + +function receiveVideos(videos) { + return { + type: 'RECEIVE_VIDEOS', + payload: videos + } +} + +export default fetchVideos; \ No newline at end of file diff --git a/src/config.js b/src/config.js index e69de29..c4a8fff 100644 --- a/src/config.js +++ b/src/config.js @@ -0,0 +1,3 @@ +export default { + apiUrl: 'https://858.ma/api' +}; \ No newline at end of file diff --git a/src/containers/Home.js b/src/containers/Home.js index 7b558f3..1c1fbde 100644 --- a/src/containers/Home.js +++ b/src/containers/Home.js @@ -2,6 +2,7 @@ import React, { Component } from 'react'; import { Link } from 'react-router-dom'; import { connect } from 'react-redux'; import testAction from '../actions/test'; +import fetchVideos from '../actions/fetchVideos'; class Home extends React.Component { clickBtn() { @@ -17,6 +18,13 @@ class Home extends React.Component {
+ +
+
+ { this.props.loading && 'Loading...'} + { this.props.videos.map(video => { + return (
{ video.title }
); + })}
); @@ -24,11 +32,14 @@ class Home extends React.Component { } const mapStateToProps = state => ({ - test: state.home.test + test: state.home.test, + loading: state.home.loading, + videos: state.home.videos }); const mapDispatchToProps = dispatch => ({ - testAction: value => dispatch(testAction(value)) + testAction: value => dispatch(testAction(value)), + fetchVideos: () => dispatch(fetchVideos()) }); export default connect(mapStateToProps, mapDispatchToProps)(Home); \ No newline at end of file diff --git a/src/reducers/home.js b/src/reducers/home.js index 8047f35..66aa6f5 100644 --- a/src/reducers/home.js +++ b/src/reducers/home.js @@ -4,6 +4,12 @@ export default function (state = {}, action) { switch (action.type) { case 'TEST_ACTION': return Object.assign({}, state, { test: action.payload }); + + case 'START_LOADING_VIDEOS': + return Object.assign({}, state, { loading: true }); + + case 'RECEIVE_VIDEOS': + return Object.assign({}, state, { loading: false, videos: action.payload }) } return state; diff --git a/src/store/configureStore.js b/src/store/configureStore.js index 01026b4..5f9b7b1 100644 --- a/src/store/configureStore.js +++ b/src/store/configureStore.js @@ -5,7 +5,9 @@ import rootReducer from '../reducers'; // Add initial state here const initialState = { 'home': { - 'test': 'foo' + 'test': 'foo', + 'loading': false, + 'videos': [] } };