Skip to content

Instantly share code, notes, and snippets.

@ustun
Created February 6, 2017 09:56
Show Gist options
  • Save ustun/f55dc03ff3f7a0c169c517b459d59810 to your computer and use it in GitHub Desktop.
Save ustun/f55dc03ff3f7a0c169c517b459d59810 to your computer and use it in GitHub Desktop.
redux reducer from immutable class
var camelCase = require('lodash.camelcase');
const {Map, Record, List} = require('immutable');
class Todo extends Record({ description: null, completed: false }) {
toggle() {
return this.set('completed', !this.completed);
}
}
const InitialTodoApp = Record({
newTodo: '',
todos: List(),
activeFilter: ''
});
class TodoApp extends InitialTodoApp {
init(data) {
return this.merge(data);
}
// action methods: kind of like IBActions
setTempTextAction({value}) {
return this.setNewTodo(value);
}
removeTodoAction({description}) {
return this.removeTodo(description);
}
addTodoAction() {
return this.addTodo();
}
// other methods
setNewTodo(newTodo) {
return this.set('newTodo', newTodo);
}
addTodo() {
return this.addTodoFromDescription(this.newTodo).resetNewTodo();
}
resetNewTodo() {
return this.set('newTodo', '');
}
addTodoFromDescription(description) {
const newTodos = this.todos.push(new Todo({ description: description }));
return this.setTodos(newTodos);
}
removeTodo(description) {
const newTodos = this.todos.filter(todo => todo.description != description);
return this.setTodos(newTodos);
}
setTodos(todos) {
return this.set('todos', todos);
}
setTodosFromJS(todosJS) {
const todos = todosJS.map(todoJS => new Todo(todoJS));
return this.setTodos(todos);
}
incompleteTodos() {
return this.todos.filter(todo => !todo.completed);
}
nIncompleteTodos() {
return this.incompleteTodos().length;
}
completeTodos() {
return this.todos.filter(todo => todo.completed);
}
nCompleteTodos() {
return this.completeTodos().length;
}
allTodos() {
return this.todos;
}
toggleTodo({description}) {
var newTodos = this.todos.map(todo => todo.description != description ? todo : todo.toggle())
return this.setTodos(newTodos);
}
describe() {
console.log(JSON.stringify(this.toJS(), null, 4));
console.log("incomplete todos", this.nIncompleteTodos());
}
}
function reducerFromRecordClass(klass) {
return function (state = new klass(), action) {
var fn = state[camelCase(action.type + '_ACTION')];
if (fn) {
return state[camelCase(action.type + '_ACTION')](action);
} else {
if (state[camelCase(action.type)]) {
console.warn('You tried to call an action method, but no such action method provided.', action.type)
}
return state;
}
}
}
const todoAppReducer = reducerFromRecordClass(TodoApp);
export default todoAppReducer;
// main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment