An open API service indexing awesome lists of open source software.

https://github.com/doches/generator-tfountain-redux-reducer

A highly opinionated Yeoman generator for redux reducers
https://github.com/doches/generator-tfountain-redux-reducer

hacktoberfest redux-reducers yeoman-generator

Last synced: over 1 year ago
JSON representation

A highly opinionated Yeoman generator for redux reducers

Awesome Lists containing this project

README

          

# Generator TFountain Redux Reducer

A strongly-opinionated [Yeoman](https://yeoman.io) generator for scaffolding out a redux reducer (and associated state slice & api calls)
based on the way that [@doches](https://github.com/doches) likes to set things up. Probably not useful for you, but _tremendously_ useful for him.

### Usage

Install Yeoman via yarn, or npm, or whatever JS package manager is hot this week:

$ yarn global add yo

Once you've got Yeoman set up, install this generator:

$ yarn global add generator-tfountain-redux-reducer

Move into the directory in your project where you want to create the new redux slice, and invoke Yeoman:

$ cd awesome-project/src/state
$ yo tfountain-redux-reducer

Tell Yeoman about your type name for this reducer, then sit back and bask in the glory of a lovely autogenerated piece of boilerplate _that you didn't have to write_. Finish your application. Move on with your life. Maybe write that novel you've always been dreaming about, or start learning the drums.

Go on. Live a little.

### Output

By way of example, the generator will ask you for singluar (e.g. "item") and plural (e.g. "items") type names, then produce a file like this:

```typescript
import { Dispatch } from "redux";
import { baseURL, headers } from "./api";

export interface IItemsState {
fetchPending: boolean;
fetched: boolean;
updatePending: boolean;

items: IItem[];
}

export const DEFAULT_ITEMS_STATE: IItemsState = {
fetchPending: false,
fetched: false,
updatePending: false,
items: [],
}

export const SET_FETCH_PENDING = "@@items/SET_FETCH_PENDING";
export const SET_UPDATE_PENDING = "@@items/SET_UPDATE_PENDING";
export const SET_ITEMS = "@@items/SET_ITEMS";
export const ADD_ITEM = "@@items/ADD_ITEM";
export const REMOVE_ITEM = "@@items/REMOVE_ITEM";
export const UPDATE_ITEM = "@@items/UPDATE_ITEM";

export function setFetchPending(pending: boolean) {
return {
type: SET_FETCH_PENDING,
pending,
};
}

export function setUpdatePending(pending: boolean) {
return {
type: SET_UPDATE_PENDING,
pending,
};
}

export function setItems(items: IItem[]) {
return {
type: SET_ITEMS,
items,
};
}

export function addItem(item: IItem) {
return {
type: ADD_ITEM,
item,
};
}

export function removeItem(itemId: number) {
return {
type: REMOVE_ITEM,
id: itemId,
};
}

function replaceItem(item: IItem) {
return {
type: UPDATE_ITEM,
item,
};
}

export function createItem(item: IItem) {
return (dispatch: Dispatch) => {
dispatch(setUpdatePending(true));
return fetch(`${baseURL}items/create`, {
headers,
method: "POST",
body: JSON.stringify(item),
})
.then((response: Response) => {
if (!response.ok) {
throw new Error();
}
return response.json();
})
.then((created: IItem) => {
dispatch(addItem(created));
})
.catch((error: any) => {
console.error(error);
})
.finally(() => {
dispatch(setUpdatePending(false));
});
}
}

export function listItems() {
return (dispatch: Dispatch) => {
dispatch(setFetchPending(true));
return fetch(`${baseURL}items/list`, {
headers,
method: "GET",
})
.then((response: Response) => {
if (!response.ok) {
throw new Error();
}
return response.json();
})
.then((items: IItem[]) => {
dispatch(setItems(items));
})
.catch((error: any) => {
console.error(error);
})
.finally(() => {
dispatch(setFetchPending(false));
});
}
}

export function updateItem(item: IItem) {
return (dispatch: Dispatch) => {
dispatch(setUpdatePending(true));
return fetch(`${baseURL}items/update`, {
headers,
method: "POST",
body: JSON.stringify(item),
})
.then((response: Response) => {
if (!response.ok) {
throw new Error();
}

dispatch(replaceItem(item));
})
.catch((error: any) => {
console.error(error);
})
.finally(() => {
dispatch(setUpdatePending(false));
});
}
}

export function deleteItem(itemId: number) {
return (dispatch: Dispatch) => {
dispatch(setUpdatePending(true));
return fetch(`${baseURL}items/${itemId}/delete`, {
headers,
method: "POST",
})
.then((response: Response) => {
if (!response.ok) {
throw new Error();
}
dispatch(removeItem(itemId));
})
.catch((error: any) => {
console.error(error);
})
.finally(() => {
dispatch(setUpdatePending(false));
});
}
}

export function items(state: IItemsState, action: any) {
if (!state) {
state = DEFAULT_ITEMS_STATE;
}

switch (action.type) {
default:
return state;
case SET_FETCH_PENDING:
return {
...state,
fetchPending: action.pending,
};
case SET_UPDATE_PENDING:
return {
...state,
updatePending: action.pending,
};
case SET_ITEMS:
return {
...state,
fetchPending: false,
fetched: true,
items: action.items,
};
case ADD_ITEM:
return {
...state,
updatePending: false,
items: [
...state.items,
action.item,
],
};
case REMOVE_ITEM:
return {
...state,
updatePending: false,
items: state.items.filter((item: IItem) => item.id != action.item.id),
};
case UPDATE_ITEM:
return {
...state,
updatePending: false,
items: state.items.map((item: IItem) => item.id === action.item.id ? action.item : item),
};
}
}
```