UNPKG

3.82 kBJavaScriptView Raw
1/* eslint consistent-return: 0, no-else-return: 0*/
2import { polyfill } from 'es6-promise';
3import request from 'axios';
4import md5 from 'spark-md5';
5import * as types from '../types';
6
7polyfill();
8
9export function makeTopicRequest(method, id, data, api = '/topic') {
10 return request[method](api + (id ? ('/' + id) : ''), data);
11}
12
13export function increment(id) {
14 return { type: types.INCREMENT_COUNT, id };
15}
16
17export function decrement(id) {
18 return { type: types.DECREMENT_COUNT, id };
19}
20
21export function destroy(id) {
22 return { type: types.DESTROY_TOPIC, id };
23}
24
25
26export function typing(text) {
27 return {
28 type: types.TYPING,
29 newTopic: text
30 };
31}
32
33/*
34 * @param data
35 * @return a simple JS object
36 */
37export function createTopicRequest(data) {
38 return {
39 type: types.CREATE_TOPIC_REQUEST,
40 id: data.id,
41 count: data.count,
42 text: data.text
43 };
44}
45
46export function createTopicSuccess() {
47 return {
48 type: types.CREATE_TOPIC_SUCCESS
49 };
50}
51
52export function createTopicFailure(data) {
53 return {
54 type: types.CREATE_TOPIC_FAILURE,
55 id: data.id,
56 error: data.error
57 };
58}
59
60export function createTopicDuplicate() {
61 return {
62 type: types.CREATE_TOPIC_DUPLICATE
63 };
64}
65
66// This action creator returns a function,
67// which will get executed by Redux-Thunk middleware
68// This function does not need to be pure, and thus allowed
69// to have side effects, including executing asynchronous API calls.
70export function createTopic(text) {
71 return (dispatch, getState) => {
72 // If the text box is empty
73 if (text.trim().length <= 0) return;
74
75 const id = md5.hash(text);
76 // Redux thunk's middleware receives the store methods `dispatch`
77 // and `getState` as parameters
78 const { topic } = getState();
79 const data = {
80 count: 1,
81 id,
82 text
83 };
84
85 // Conditional dispatch
86 // If the topic already exists, make sure we emit a dispatch event
87 if (topic.topics.filter(topicItem => topicItem.id === id).length > 0) {
88 // Currently there is no reducer that changes state for this
89 // For production you would ideally have a message reducer that
90 // notifies the user of a duplicate topic
91 return dispatch(createTopicDuplicate());
92 }
93
94 // First dispatch an optimistic update
95 dispatch(createTopicRequest(data));
96
97 return makeTopicRequest('post', id, data)
98 .then((res) => {
99 if (res.status === 200) {
100 // We can actually dispatch a CREATE_TOPIC_SUCCESS
101 // on success, but I've opted to leave that out
102 // since we already did an optimistic update
103 // We could return res.json();
104 return dispatch(createTopicSuccess());
105 }
106 })
107 .catch(() => {
108 return dispatch(createTopicFailure({ id, error: 'Oops! Something went wrong and we couldn\'t create your topic'}));
109 });
110 };
111}
112
113export function incrementCount(id) {
114 return (dispatch) => {
115 return makeTopicRequest('put', id, {
116 isFull: false,
117 isIncrement: true
118 })
119 .then(() => dispatch(increment(id)))
120 .catch(() => dispatch(createTopicFailure({id, error: 'Oops! Something went wrong and we couldn\'t add your vote'})));
121 };
122}
123
124export function decrementCount(id) {
125 return (dispatch) => {
126 return makeTopicRequest('put', id, {
127 isFull: false,
128 isIncrement: false
129 })
130 .then(() => dispatch(decrement(id)))
131 .catch(() => dispatch(createTopicFailure({id, error: 'Oops! Something went wrong and we couldn\'t add your vote'})));
132 };
133}
134
135export function destroyTopic(id) {
136 return (dispatch) => {
137 return makeTopicRequest('delete', id)
138 .then(() => dispatch(destroy(id)))
139 .catch(() => dispatch(createTopicFailure({id,
140 error: 'Oops! Something went wrong and we couldn\'t add your vote'})));
141 };
142}