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", diff --git a/5-redux-react/src/js/actions/tweetsActions.js b/5-redux-react/src/js/actions/tweetsActions.js index edf6ed0d..8fe0962f 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)}) + }) } } 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 new file mode 100644 index 00000000..dc284a98 --- /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 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 187a1467..3bccc03b 100644 --- a/5-redux-react/src/js/reducers/tweetsReducer.js +++ b/5-redux-react/src/js/reducers/tweetsReducer.js @@ -1,3 +1,5 @@ +import Tweets from "../factories/TweetFactory" + 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: new Tweets(action.payload).getAll(), } } case "ADD_TWEET": {