Skip to content

Instantly share code, notes, and snippets.

@good-idea
Created January 9, 2018 03:30
Show Gist options
  • Save good-idea/e2b90e025c3c9421d1a9e96ab1370632 to your computer and use it in GitHub Desktop.
Save good-idea/e2b90e025c3c9421d1a9e96ab1370632 to your computer and use it in GitHub Desktop.
Login Controller with State Machine
// @flow
import React from 'react'
import axios from 'axios'
import R from 'ramda'
import Login from './Login'
/**
* LoginController
*/
const loginMachine = {
start: {
SUBMIT: 'thinking',
},
thinking: {
LOGIN_SUCCESS: 'success',
LOGIN_FAILURE: 'error',
},
error: {
SUBMIT: 'thinking',
},
success: {
CANCEL: 'start',
},
}
type Props = {}
type State = {
loginState: string,
loginError: string,
}
type LoginFormData = {
email: string,
password: string,
}
type Action = {
type: string,
errorMessage?: string,
formData?: LoginFormData,
}
class LoginController extends React.Component<Props, State> {
constructor(props: {}) {
super(props)
this.state = {
loginError: '',
loginState: 'start',
}
}
command(nextState: string, action: Action) {
switch (nextState) {
case 'thinking':
return this.attemptLogin(action.formData)
case 'error':
return {
loginError: action.errorMessage,
}
default:
break
}
}
attemptLogin(credentials: LoginFormData): void {
axios
.post('//localhost:3000/auth/login', credentials)
.then((response) => {
console.log(response)
this.transition({ type: 'LOGIN_SUCCESS' })
})
.catch((err) => {
console.log(Object.keys(err))
console.log(err.response)
const errorMessage = R.path(['response', 'data', 'message'], err).toString() || 'Invalid credentials'
this.transition({ type: 'LOGIN_FAILURE', errorMessage })
})
}
handleLogin = (formData: LoginFormData) => {
this.transition({ type: 'SUBMIT', formData })
}
transition(action: Action) {
const currentState = this.state.loginState
const nextLoginState = loginMachine[currentState][action.type]
if (nextLoginState) {
const nextState = this.command(nextLoginState, action)
this.setState({
loginState: nextLoginState,
...nextState,
})
}
}
render() {
return <Login loginError={this.state.loginError} loginState={this.state.loginState} handleLogin={this.handleLogin} />
}
}
export default LoginController
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment