/** @module users/state */ import { call, put, takeEvery } from 'redux-saga/effects' import jwt from 'jwt-simple' /** * state.js * * Collection of everything which has to do with state changes. **/ /** actionTypes define what actions are handeled by the reducer. */ export const actions = { loginRequest: (data) => { return { type: 'USER/LOGIN_REQUEST', data } }, loginSuccess: (token, tokenData) => { return { type: 'USER/LOGIN_SUCCESS', token, tokenData } }, loginFailure: () => { return { type: 'USER/LOGIN_FAILURE' } }, getUserList: () => { return { type: 'USER/GET_USER_LIST' } }, userListSuccess: (users) => { return { type: 'USER/GET_USER_LIST_SUCCESS', users } }, userListFailure: () => { return { type: 'USER/GET_USER_LIST_FAILURE' } }, addUserRequest: (data) => { return { type: 'USER/ADD_REQUEST', data } }, addUserSuccess: (data) => { return { type: 'USER/ADD_SUCCESS', data } }, addUserFailure: () => { return { type: 'USER/ADD_FAILURE' } } } console.log('State actions', actions) /** state definition */ export const state = { loginRequested: false, userListRequested: false, userListInitialized: false, users: [], token: null, tokenData: null } console.log('State state', state) /** reducer is called by the redux dispatcher and handles all component actions */ export function reducer (state = [], action) { switch (action.type) { case 'USER/LOGIN_REQUEST': return { ...state, loginRequested: true } case 'USER/LOGIN_SUCCESS': return { ...state, loginRequested: false, token: action.token, tokenData: action.tokenData } case 'USER/LOGIN_FAILURE': return { ...state, loginRequested: false } case 'USER/GET_USER_LIST': return { ...state, userListRequested: true, userListInitialized: true } case 'USER/GET_USER_LIST_SUCCESS': return { ...state, userListRequested: false, users: action.users } case 'USER/GET_USER_LIST_FAILURE': return { ...state, userListRequested: false } default: return state } } function * login (action) { try { console.log('User login requested', action.data) const response = yield call(fetch, 'http://localhost:3002/authenticate/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(action.data) }) const responseJson = yield response.json() if (response.status != 200) { console.log(responseJson.msg) throw new Error(responseJson.msg) } const { token } = responseJson const tokenData = jwt.decode(token, null, true) localStorage.setItem('accessToken', token) localStorage.setItem('accessTokenData', JSON.stringify(tokenData)) console.log('User login success!', token, tokenData) yield put(actions.loginSuccess(token, tokenData)) } catch (error) { console.log('User login failure!', error) yield put(actions.loginFailure(error)) } } function * getUserList (action) { try { const token = localStorage.getItem('accessToken') console.log('User list requested', action, token) const response = yield call(fetch, 'http://localhost:3002/api/users', { method: 'GET', headers: new Headers({ 'Content-Type': 'application/json', 'x-access-token': token }) }) console.log('Received response') const responseJson = yield response.json() if (response.status != 200) { console.log('User list received error', responseJson.msg) throw new Error(responseJson.msg) } console.log('Get user list success!', responseJson.users) yield put(actions.userListSuccess(responseJson.users)) } catch (error) { console.log('Get user list failure!', error) yield put(actions.userListFailure(error.toString())) } } /** sagas are asynchronous workers (JS generators) to handle the state. */ export function * saga () { console.log('User saga started.') yield takeEvery('USER/LOGIN_REQUEST', login) yield takeEvery('USER/GET_USER_LIST', getUserList) }