DEV Community

Cover image for Flip it and Redux it!
JaredHarbison
JaredHarbison

Posted on • Edited on

1 1

Flip it and Redux it!

Rails + React + Redux - Pt 9


In the last post I setup the index.js and App.js files for the project. I also created a file structure to work from as the project grows. Here I'll focus on the actions files, with reducers in the next post.


Let's get started!


The queen_actions.js file holds fetchQueens and updateQueen. For now, I'm not planning on users being able to add or delete a queen.

import {
LOADING_QUEENS,
FETCH_QUEENS,
UPDATE_QUEEN
} from './types'
export const fetchQueens = () => {
return (dispatch) => {
dispatch({ type: LOADING_QUEENS })
return fetch(`/queens`)
.then(res => res.json())
.then(jsonResponse => {
dispatch({
type: FETCH_QUEENS,
payload: jsonResponse
})
})
}
}
export const updateQueen = (queen) => {
return (dispatch) => {
return fetch(`/queens/${queen.id}`, {
method: "PATCH",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(queen)
}).then(res => res.json()).then(data => {
dispatch({
type: UPDATE_QUEEN,
payload: data})
})
}
}

The trivia_actions.js file is a little more fun. Because trivia (and quotes) must belong to a queen, they add a thin layer of complexity to the interaction with the Rails API. I'm adding the gist for the trivia actions file, but not the quotes file as it is nearly exactly the same.

import {
UPDATE_QUEEN_TRIVIA,
DELETE_QUEEN_TRIVIUM
} from './types'
export const addTrivia = (trivium) => {
return (dispatch) => {
return fetch(`/trivia`, {
method: "post",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(trivium)
}).then(res => res.json()).then(data => {
dispatch({type:UPDATE_QUEEN_TRIVIA, payload: data})
})
};
};
export const deleteTrivium = (trivium) => {
return (dispatch) => {
return fetch(`/trivia/${trivium.id}`, {
method: "delete",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(trivium)
}).then(res => res.text()).then(data => {
dispatch({type:DELETE_QUEEN_TRIVIUM, payload: data})
})
};
};

The season_actions.js file is, for now, only the fetch call. I will eventually need to update this so users can update appearance attributes.

import {
LOADING_SEASONS,
FETCH_SEASONS,
UPDATE_SEASON
} from './types'
export const fetchSeasons = () => {
return (dispatch) => {
dispatch({ type: LOADING_SEASONS })
return fetch('/seasons')
.then(res => res.json())
.then(jsonResponse => {
dispatch({
type: FETCH_SEASONS,
payload: jsonResponse
})
})
}
}

I imagined I'll need a common_actions.js file as the project grows to avoid creating the same function in multiple files.

export const arrayToSentence = (a) => {
if (a.length === 1) return a[0];
const firsts = a.slice(0, a.length -1);
const last = a[a.length -1];
return firsts.join(', ') + ' and ' + last;
}

I created a types.js file to define and export the action constants.

export const FETCH_QUEENS = 'FETCH_QUEENS';
export const LOADING_QUEENS = 'LOADING_QUEENS';
export const UPDATE_QUEEN_TRIVIA = 'UPDATE_QUEEN_TRIVIA';
export const DELETE_QUEEN_TRIVIUM = 'DELETE_QUEEN_TRIVIUM';
export const UPDATE_QUEEN = 'UPDATE_QUEEN';
export const FETCH_QUEEN = 'FETCH_QUEEN';
export const ADD_QUEEN_QUOTE = 'ADD_QUEEN_QUOTE';
export const DELETE_QUEEN_QUOTE = 'DELETE_QUEEN_QUOTE';
export const LOADING_SEASONS = 'LOADING_SEASONS';
export const FETCH_SEASONS = 'FETCH_SEASONS';
export const UPDATE_SEASON = 'UPDATE_SEASON';
view raw types.js hosted with ❤ by GitHub

Even at the beginning stages of this project, indexing the actions files was an obvious necessity to avoid massive files.

export * from './queenActions';
export * from './quoteActions';
export * from './triviaActions';
export * from './seasonActions';
export * from './commonActions';
view raw index.js hosted with ❤ by GitHub

When I started thinking of actions in a similar way to how I think of controllers in a full-on Rails application, they started to make a little more sense to me. Reducers is where I was really thrown, which I can't wait to get back into next week!


That's all folks!

Top comments (0)