From 2ff301bdf50f4453b4d9cc687b36d8b36bc310f0 Mon Sep 17 00:00:00 2001 From: FelipeBarrosCruz Date: Fri, 5 May 2017 09:17:07 -0300 Subject: [PATCH 1/6] Add method to filter payload data and abstract the url to request --- 5-redux-react/src/js/actions/tweetsActions.js | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/5-redux-react/src/js/actions/tweetsActions.js b/5-redux-react/src/js/actions/tweetsActions.js index edf6ed0d..2c479c72 100644 --- a/5-redux-react/src/js/actions/tweetsActions.js +++ b/5-redux-react/src/js/actions/tweetsActions.js @@ -1,6 +1,26 @@ import axios from "axios"; export function fetchTweets() { + const TWEETS_USER = 'learncode'; + + function filterPayloadDataToReturn(data) { + if (!Array.isArray(data)) return []; + return data.filter(value => !!value).reduce((merge, value) => { + if (value.myArray && Array.isArray(value.myArray)) { + merge = merge.concat(value.myArray); + } + return merge; + }, []); + } + + function buildTweetsUrl(user) { + return `http://rest.learncode.academy/api/${user}/tweets`; + } + + function requestTweets(url, done) { + axios.get(url).then(response => done(null, response)).catch(err => done(err, null)); + } + return function(dispatch) { /* http://rest.learncode.academy is a public test server, so another user's experimentation can break your tests @@ -8,13 +28,12 @@ export function fetchTweets() { - change "reacttest" below to any other username - post some tweets to http://rest.learncode.academy/api/yourusername/tweets */ - axios.get("http://rest.learncode.academy/api/reacttest/tweets") - .then((response) => { - dispatch({type: "FETCH_TWEETS_FULFILLED", payload: response.data}) - }) - .catch((err) => { - dispatch({type: "FETCH_TWEETS_REJECTED", payload: err}) - }) + requestTweets(buildTweetsUrl(TWEETS_USER), (err, response) => { + if (err || !response && !response.data || Array.isArray(response.data) && !response.data.length) { + return dispatch({type: "FETCH_TWEETS_REJECTED", payload: err || new Error('Tweets are empty')}); + } + return dispatch({type: "FETCH_TWEETS_FULFILLED", payload: filterPayloadDataToReturn(response.data)}); + }) } } From a7f8f73a9016a474876bc3cb0fcd040c6fa65a69 Mon Sep 17 00:00:00 2001 From: FelipeBarrosCruz Date: Fri, 5 May 2017 09:17:57 -0300 Subject: [PATCH 2/6] Change the pure payload value to model structure data --- 5-redux-react/src/js/reducers/tweetsReducer.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/5-redux-react/src/js/reducers/tweetsReducer.js b/5-redux-react/src/js/reducers/tweetsReducer.js index 187a1467..ae0480ef 100644 --- a/5-redux-react/src/js/reducers/tweetsReducer.js +++ b/5-redux-react/src/js/reducers/tweetsReducer.js @@ -1,3 +1,5 @@ +import Tweet from "../entities/tweetEntity" + export default function reducer(state={ tweets: [], fetching: false, @@ -17,7 +19,7 @@ export default function reducer(state={ ...state, fetching: false, fetched: true, - tweets: action.payload, + tweets: action.payload.map(value => new Tweet(value)), } } case "ADD_TWEET": { From eb1b64157468ad02e3af6332f3e6c4a02165510a Mon Sep 17 00:00:00 2001 From: FelipeBarrosCruz Date: Fri, 5 May 2017 09:18:40 -0300 Subject: [PATCH 3/6] Add entities folder to setup model strucuture of tweets --- 5-redux-react/src/js/entities/tweetEntity.js | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 5-redux-react/src/js/entities/tweetEntity.js diff --git a/5-redux-react/src/js/entities/tweetEntity.js b/5-redux-react/src/js/entities/tweetEntity.js new file mode 100644 index 00000000..c07cff07 --- /dev/null +++ b/5-redux-react/src/js/entities/tweetEntity.js @@ -0,0 +1,8 @@ +export default class Tweet { + constructor (value) { + if (value.id && value.tweet) { + this.id = value.id; + this.text = value.tweet; + } + } +} \ No newline at end of file From 19a24e54d9ad9c87f126cac8e4b7b7150503ee35 Mon Sep 17 00:00:00 2001 From: FelipeBarrosCruz Date: Fri, 5 May 2017 09:42:10 -0300 Subject: [PATCH 4/6] Add lodash to dependencies --- 5-redux-react/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/5-redux-react/package.json b/5-redux-react/package.json index bf4c684e..b6a273d8 100644 --- a/5-redux-react/package.json +++ b/5-redux-react/package.json @@ -14,6 +14,7 @@ "babel-preset-es2015": "^6.3.13", "babel-preset-react": "^6.3.13", "babel-preset-stage-0": "^6.3.13", + "lodash": "^4.17.4", "react": "^0.14.6", "react-dom": "^0.14.6", "react-redux": "^4.4.5", From b87cc63b13774664ab6f97015963232c58548851 Mon Sep 17 00:00:00 2001 From: FelipeBarrosCruz Date: Fri, 5 May 2017 09:43:25 -0300 Subject: [PATCH 5/6] Remove semicolon to padronize the syntax --- 5-redux-react/src/js/actions/tweetsActions.js | 14 +++++++------- 5-redux-react/src/js/components/Layout.js | 2 +- 5-redux-react/src/js/entities/tweetEntity.js | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/5-redux-react/src/js/actions/tweetsActions.js b/5-redux-react/src/js/actions/tweetsActions.js index 2c479c72..8fe0962f 100644 --- a/5-redux-react/src/js/actions/tweetsActions.js +++ b/5-redux-react/src/js/actions/tweetsActions.js @@ -7,18 +7,18 @@ export function fetchTweets() { if (!Array.isArray(data)) return []; return data.filter(value => !!value).reduce((merge, value) => { if (value.myArray && Array.isArray(value.myArray)) { - merge = merge.concat(value.myArray); + merge = merge.concat(value.myArray) } - return merge; - }, []); + return merge + }, []) } function buildTweetsUrl(user) { - return `http://rest.learncode.academy/api/${user}/tweets`; + return `http://rest.learncode.academy/api/${user}/tweets` } function requestTweets(url, done) { - axios.get(url).then(response => done(null, response)).catch(err => done(err, null)); + axios.get(url).then(response => done(null, response)).catch(err => done(err, null)) } return function(dispatch) { @@ -30,9 +30,9 @@ export function fetchTweets() { */ requestTweets(buildTweetsUrl(TWEETS_USER), (err, response) => { if (err || !response && !response.data || Array.isArray(response.data) && !response.data.length) { - return dispatch({type: "FETCH_TWEETS_REJECTED", payload: err || new Error('Tweets are empty')}); + return dispatch({type: "FETCH_TWEETS_REJECTED", payload: err || new Error('Tweets are empty')}) } - return dispatch({type: "FETCH_TWEETS_FULFILLED", payload: filterPayloadDataToReturn(response.data)}); + return dispatch({type: "FETCH_TWEETS_FULFILLED", payload: filterPayloadDataToReturn(response.data)}) }) } } diff --git a/5-redux-react/src/js/components/Layout.js b/5-redux-react/src/js/components/Layout.js index 8d416cd7..a738c48d 100644 --- a/5-redux-react/src/js/components/Layout.js +++ b/5-redux-react/src/js/components/Layout.js @@ -21,7 +21,7 @@ export default class Layout extends React.Component { } render() { - const { user, tweets } = this.props; + const { user, tweets } = this.props if (!tweets.length) { return diff --git a/5-redux-react/src/js/entities/tweetEntity.js b/5-redux-react/src/js/entities/tweetEntity.js index c07cff07..dc284a98 100644 --- a/5-redux-react/src/js/entities/tweetEntity.js +++ b/5-redux-react/src/js/entities/tweetEntity.js @@ -1,8 +1,8 @@ export default class Tweet { constructor (value) { if (value.id && value.tweet) { - this.id = value.id; - this.text = value.tweet; + this.id = value.id + this.text = value.tweet } } } \ No newline at end of file From a41d472ff3510dc7ff2d6aa4eba686b2f3aa2ce1 Mon Sep 17 00:00:00 2001 From: FelipeBarrosCruz Date: Fri, 5 May 2017 09:46:38 -0300 Subject: [PATCH 6/6] Add factory to generate the model of tweets and remove duplicate tweets --- 5-redux-react/src/js/factories/tweetFactory.js | 15 +++++++++++++++ 5-redux-react/src/js/reducers/tweetsReducer.js | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 5-redux-react/src/js/factories/tweetFactory.js diff --git a/5-redux-react/src/js/factories/tweetFactory.js b/5-redux-react/src/js/factories/tweetFactory.js new file mode 100644 index 00000000..b38cd322 --- /dev/null +++ b/5-redux-react/src/js/factories/tweetFactory.js @@ -0,0 +1,15 @@ +import Tweet from "../entities/tweetEntity" +import _ from "lodash" + +export default class TweetFactory { + constructor (data) { + this.tweets = [] + if (Array.isArray(data)) { + this.tweets = _.uniqBy(data, 'id').map(value => new Tweet(value)) + } + } + + getAll () { + return this.tweets + } +} \ No newline at end of file diff --git a/5-redux-react/src/js/reducers/tweetsReducer.js b/5-redux-react/src/js/reducers/tweetsReducer.js index ae0480ef..3bccc03b 100644 --- a/5-redux-react/src/js/reducers/tweetsReducer.js +++ b/5-redux-react/src/js/reducers/tweetsReducer.js @@ -1,4 +1,4 @@ -import Tweet from "../entities/tweetEntity" +import Tweets from "../factories/TweetFactory" export default function reducer(state={ tweets: [], @@ -19,7 +19,7 @@ export default function reducer(state={ ...state, fetching: false, fetched: true, - tweets: action.payload.map(value => new Tweet(value)), + tweets: new Tweets(action.payload).getAll(), } } case "ADD_TWEET": {