Skip to content

Instantly share code, notes, and snippets.

@rbinksy
Created June 22, 2018 13:34
Show Gist options
  • Select an option

  • Save rbinksy/a2fa04d4e0af5926a6f75ca41ccab80a to your computer and use it in GitHub Desktop.

Select an option

Save rbinksy/a2fa04d4e0af5926a6f75ca41ccab80a to your computer and use it in GitHub Desktop.
Typescript Connected Component
interface TodosFindResponse {
promiseData?: TodoEntity[];
promiseError?: object;
loaded: boolean;
}
interface AddedTodosState {
addedTodos: TodoEntity[];
addTodoToState: (todo: TodoEntity) => void;
}
interface SearchFilterState {
searchText: string;
setSearchText: (text: string) => void;
}
type TodosListDataProps = TodosFindResponse &
UrlState &
AddedTodosState;
const selectFilteredTodos = createSelector<TodosListDataProps, TodoEntity[], string, TodoEntity[], TodoEntity[]>(
props => props.promiseData || [],
props => props.searchText || '',
props => props.addedTodos,
(todos, searchText, addedTodos) => (
(searchText.length > 0)
? todos.filter(todo => todo.text.includes(searchText))
: todos
).concat(addedTodos)
);
// map from TodosListDataProps to TodosSearchProps
const selectSearchProps = (props: TodosListDataProps): TodosSearchProps => ({
searchText: props.searchText,
setSearchText: props.setSearchText
});
// map from TodosListDataProps to TodosListProps
const TodosListPage = compose<TodosListProps, {}>(
withPromise<TodoEntity[]>(() => TodosService.find()),
withState<AddedTodosState>('addedTodos', 'addTodoToState', []),
withState<SearchFilterState>('searchText', 'setSearchText', ''),
mapProps<TodosListProps, TodosListDataProps>(props => ({
addTodo: (todo: TodoEntity) => TodosService.create(todo)
.then(addedTodo => props.addTodoToState(addedTodo)),
todos: selectFilteredTodos(props),
search: selectSearchProps(props)
})
)(TodosList);
interface TodosFindResponse {
promiseData?: TodoEntity[];
promiseError?: object;
loaded: boolean;
}
interface AddedTodosState {
addedTodos: TodoEntity[];
addTodoToState: (todo: TodoEntity) => void;
}
interface SearchFilterState {
searchText: string;
setSearchText: (text: string) => void;
}
type TodosListDataProps = TodosFindResponse &
UrlState &
AddedTodosState;
const selectFilteredTodos = createSelector<TodosListDataProps, TodoEntity[], string, TodoEntity[], TodoEntity[]>(
props => props.promiseData || [],
props => props.searchText || '',
props => props.addedTodos,
(todos, searchText, addedTodos) => (
(searchText.length > 0)
? todos.filter(todo => todo.text.includes(searchText))
: todos
).concat(addedTodos)
);
// map from TodosListDataProps to TodosSearchProps
const selectSearchProps = (props: TodosListDataProps): TodosSearchProps => ({
searchText: props.searchText,
setSearchText: props.setSearchText
});
// map from TodosListDataProps to TodosListProps
const TodosListPage = compose<TodosListProps, {}>(
withPromise<TodoEntity[]>(() => TodosService.find()),
withState<AddedTodosState>('addedTodos', 'addTodoToState', []),
withState<SearchFilterState>('searchText', 'setSearchText', ''),
mapProps<TodosListProps, TodosListDataProps>(props => ({
addTodo: (todo: TodoEntity) => TodosService.create(todo)
.then(addedTodo => props.addTodoToState(addedTodo)),
todos: selectFilteredTodos(props),
search: selectSearchProps(props)
})
)(TodosList);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment