I have created an authentification system in react with redux and axios but I can`t figure out how to render the data in my components.
This is my actions/auth.js:
import axios from 'axios';
import {
SIGNUP_SUCCESS,
SIGNUP_FAIL,
LOGIN_SUCCESS,
LOGIN_FAIL,
ACTIVATION_SUCCESS,
ACTIVATION_FAIL,
RESET_PASSWORD_SUCCESS,
RESET_PASSWORD_FAIL,
RESET_PASSWORD_CONFIRM_SUCCESS,
RESET_PASSWORD_CONFIRM_FAIL,
LOGOUT,
USER_LOADED_SUCCESS,
USER_LOADED_FAIL,
AUTHENTICATED_FAIL,
AUTHENTICATED_SUCCESS
} from './types';
export const checkAuthenticated = () => async dispatch => {
if (typeof window == 'undefined') {
dispatch({
type: AUTHENTICATED_FAIL
});
}
if (localStorage.getItem('access')) {
const config = {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
};
const body = JSON.stringify({ token: localStorage.getItem('access') });
try {
const res = await axios.post(`${process.env.REACT_APP_API_URL}/auth/jwt/verify/`, body, config);
if (res.data.code !== 'token_not_valid') {
dispatch({
type: AUTHENTICATED_SUCCESS
});
} else {
dispatch({
type: AUTHENTICATED_FAIL
});
}
} catch (err) {
dispatch({
type: AUTHENTICATED_FAIL
});
}
} else {
dispatch({
type: AUTHENTICATED_FAIL
});
}
};
export const load_user = () => async dispatch => {
if (localStorage.getItem('access')) {
const config = {
headers: {
'Content-Type': 'application/json',
'Authorization': `JWT ${localStorage.getItem('access')}`,
'Accept': 'application/json'
}
};
try {
const res = await axios.get(`${process.env.REACT_APP_API_URL}/auth/users/me/`, config);
dispatch({
type: USER_LOADED_SUCCESS,
payload: res.data
});
} catch (err) {
dispatch({
type: USER_LOADED_FAIL
});
}
} else {
dispatch({
type: USER_LOADED_FAIL
});
}
};
export const login = (email, password) => async dispatch => {
const config = {
headers: {
'Content-Type': 'application/json'
}
};
const body = JSON.stringify({ email, password });
try {
const res = await axios.post(`${process.env.REACT_APP_API_URL}/auth/jwt/create/`, body, config);
dispatch({
type: LOGIN_SUCCESS,
payload: res.data
});
dispatch(load_user());
} catch (err) {
dispatch({
type: LOGIN_FAIL
});
}
};
export const logout = () => dispatch => {
dispatch({ type: LOGOUT });
};
This is my reducers/auth.js:
import {
SIGNUP_SUCCESS,
SIGNUP_FAIL,
LOGIN_SUCCESS,
LOGIN_FAIL,
LOGOUT,
AUTHENTICATED_FAIL,
AUTHENTICATED_SUCCESS,
USER_LOADED_SUCCESS,
USER_LOADED_FAIL
} from '../actions/types';
const initialState = {
access: localStorage.getItem('access'),
refresh: localStorage.getItem('refresh'),
isAuthenticated: null,
user: null
};
export default function(state = initialState, action) {
const { type, payload } = action;
switch(type) {
case AUTHENTICATED_SUCCESS:
return {
...state,
isAuthenticated: true
}
case LOGIN_SUCCESS:
localStorage.setItem('access', payload.access);
return {
...state,
isAuthenticated: true,
access: payload.access,
refresh: payload.refresh
}
case USER_LOADED_SUCCESS:
return {
...state,
user: payload
}
case AUTHENTICATED_FAIL:
return {
...state,
isAuthenticated: false
}
case USER_LOADED_FAIL:
return {
...state,
user: null
}
case LOGIN_FAIL:
case LOGOUT:
localStorage.removeItem('access');
localStorage.removeItem('refresh');
return{
...state,
access: null,
refresh: null,
isAuthenticated: false,
user: null
}
default:
return state
}
}
If I log in and use the redux Devtool I can see this state:
{
auth: {
access: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjAzNDgzODY1LCJqdGkiOiJhYTAzYzIzNTUwN2M0YTkxYjA2NjNmNDc0ZTU2MjIxMSIsInVzZXJfaWQiOjF9.Jyld4U7i6EqmsNoi0_qT9O9Kcu1TiEuyLLYCWWaoBrU',
refresh: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTYwMzU2OTk2NSwianRpIjoiOWIzMWIyN2M1ODkyNDRiZDk3Y2EwMDI1NTY2Mzk3ZWMiLCJ1c2VyX2lkIjoxfQ.UgH_753OoWD3NXiwPwa1645_vIHUl-FwyvQMJWMgHtk',
isAuthenticated: true,
user: {
name: 'Jonas Levin',
id: 1,
email: 'jonaslevin1903#gmail.com'
}
}
}
But I can`t figure out how to display the data, for example user.name.
I already tried to use mapStateToProps in one of my components but I get the error: "TypeError: Cannot read property 'name' of undefined"
const mapStateToProps = state => ({
userName: state.user.name,
userEmail: state.user.email
});
Edit
This is the response data that I get. But as you can see there is another API call which is still from the login page where I was on before I got redirected to '/' and that light red /me call has an error message in it because when your on the login page you don`t have an access token.
How can I access this response data in my Components to render the Name?
Store.js:
import { createStore, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
const initialState = {};
const middleware = [thunk];
const store = createStore(
rootReducer,
initialState,
composeWithDevTools(applyMiddleware(...middleware))
);
export default store;
I managed to access the username in my layout.js file by adding the state to the props:
const mapStateToProps = (state, ownProps) => {
return {
isAuthenticated: state.auth.isAuthenticated,
user: state.auth.user,
props: ownProps
}
};
I used ownProps to be able to also use props.children in the layout container. Than I gave tham as parameters to the layout container and was able to access the username with user.name.
I´m not entirely sure why it worked now and not before when I already tried to use mapStateToProps.
this is how you should do it access auth reducer then th user
const mapStateToProps = state => ({
userName: state.auth.user.name,
userEmail: state.auth.user.email
});
this is how redux works , let's say this is your store
import {cartReducer} from './reducers/CartReducer'
import { authReducer } from './reducers/AuthReducer'
import { ordersReducer } from './reducers/OrdersReducer'
import { errorsReducer } from './reducers/ErrorsReducer'
const initialState={
products:{
items:[],
filterdProducts:[]
},
cart:{
items:[],
},
orders:{
items:[],
canOrder:true,
},
auth: {
access: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjAzNDgzODY1LCJqdGkiOiJhYTAzYzIzNTUwN2M0YTkxYjA2NjNmNDc0ZTU2MjIxMSIsInVzZXJfaWQiOjF9.Jyld4U7i6EqmsNoi0_qT9O9Kcu1TiEuyLLYCWWaoBrU',
refresh: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTYwMzU2OTk2NSwianRpIjoiOWIzMWIyN2M1ODkyNDRiZDk3Y2EwMDI1NTY2Mzk3ZWMiLCJ1c2VyX2lkIjoxfQ.UgH_753OoWD3NXiwPwa1645_vIHUl-FwyvQMJWMgHtk',
isAuthenticated: true,
user: {
name: 'Jonas Levin',
id: 1,
email: 'jonaslevin1903#gmail.com'
}
},
error:{
msg:null,
status:null,
id:null
}
}
const composeEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
const store = createStore(combineReducers({
products: productsReducer,
cart : cartReducer ,
orders : ordersReducer ,
auth : authReducer,
error : errorsReducer ,
}),
initialState,
composeEnhancer(applyMiddleware(thunk))
)
export default store
if you want to access user from any other component you'mm need to access auth reducer first , same for items you can either access products.items or cart .items and so on
If you use a functional component, you could use useSelector hook.
const user = useSelector(state => state.auth.user)
Related
I have created an app using react native typescript and redux. I have successfully configured the store and everything. But the problem is when I tried to login, I dispatch payload to authReducer and it returns undefined.
store.tsx
import AsyncStorage from "#react-native-async-storage/async-storage";
import { createStore, applyMiddleware } from "redux";
import { createLogger } from 'redux-logger';
import { persistStore, persistReducer } from "redux-persist";
import rootReducer from "../_redux/reducers/index";
const persistConfig = {
key: "root",
storage: AsyncStorage,
whitelist: ["authReducer"],
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
const store = createStore(persistedReducer, applyMiddleware(createLogger()));
let persistor = persistStore(store);
export { store, persistor };
authReducer.tsx
export const initState = {
isAuthenticated: false,
user: {},
token: "No Token",
};
const rootReducer = (state = initState, action: any) => {
if (action.type === "LOG_IN") {
const { isAuthenticated, user, token } = action.payload;
return {
...state,
isAuthenticated,
user,
token,
};
}
if (action.type === "LOG_OUT") {
const { isAuthenticated, user, token } = action.payload;
return {
...state,
isAuthenticated,
user,
token,
};
}
if (action.type === "UPDATE_PROFILE") {
return {
...state,
user: {
...state.user,
name: action.name,
email: action.email,
phone: action.phone,
},
};
}
return state;
};
export default rootReducer;
Login.tsx
axios
.post(`${BASE_URL}/login`, {
email: email,
password: password,
})
.then((response) => {
setLoading(false);
if (response.data.success) {
// response.data.user_data = {user_id: 1, user_name: "Jithin Varghese", user_email: "jithin#gmail.com", user_phone: "1234567890"}
// response.data.token = 1
logIn(true, response.data.user_data, response.data.token);
navigation.navigate("Home");
}
})
.catch((error) => {
console.log(error);
setLoading(false);
});
};
const mapDispatchToProps = (dispatch: any) => ({
logIn: ({ isAuthenticated, user, token }: any) => {
dispatch({
type: "LOG_IN",
payload: {
isAuthenticated,
user,
token,
},
});
},
});
const mapStateToProps = (state: any) => ({
isAuthenticated: state.authReducer.isAuthenticated,
user: state.authReducer.user,
token: state.authReducer.token,
});
export default connect(mapStateToProps, mapDispatchToProps)(Login);
The isAuthenticated, user, token is always undefined after dispatch. You can check the below screenshot for more details.
Initial load
After login axios call dispatch (logIn(true, response.data.user_data, response.data.token))
I have tried a lot to find a solution and I couldn't find any. What is the problem. I cannot figure this out.
I think prev state is causing the problem. It is empty initially.
I think you're passing 3 args to "logIn" instead of 1 arg as an object
instead of calling it like: logIn(true, response.data.user_data, response.data.token);
it should be like
logIn({isAuthenticated:true, user:response.data.user_data, token:response.data.token});
You are not passing data correctly in Action. You need to pass one argument and you are passing three arguments.
You need to pass data like this
logIn(isAuthenticated:true , user: response.data.user_data, token: response.data.token)
I'm creating to do list app so I created API using laravel and it works fine . The scenario is when user login I dispatch an action to check his email and password then update the store in redux with the user tasks . The tasks reach to the reducer fine but I cannot get it in the TasksComponent I get undefined when console.log(this.props.tasks) or even console.log(this.props.isLoading)
The reducer login
import * as ActionTypes from './ActionTypes';
export const Login = (state = {
tasks: [],
categories: [],
error: null,
isLoading: true
}, action) => {
switch(action.type) {
case ActionTypes.AUTH_LOADING:
return {...state, tasks:[], categories:[], error: null, isLoading: true}
case ActionTypes.AUTH_SUCCESS:
console.log(action.payload.user.tasks)
return {...state, tasks: action.payload.user.tasks, categories: action.payload.user.categories,error: null, isLoading: false}
case ActionTypes.AUTH_FAIL:
return {...state, tasks:[], categories:[], error: action.error, isLoading: false}
default:
return state;
}
}
The Action creator
import * as ActionTypes from './ActionTypes';
import { baseUrl } from '../shared/baseUrl';
export const authSuccess = (authData) => ({
type: ActionTypes.AUTH_SUCCESS,
payload: authData
});
export const authFail = (error) => ({
type: ActionTypes.AUTH_FAIL,
error: error
});
export const authLoading = () =>({
type: ActionTypes.AUTH_LOADING
})
export const auth = (email, password) => dispatch => {
dispatch(authLoading());
const user = {
email: email,
password: password
}
return fetch('http://localhost:8000/api/users/login',{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(user)
})
.then(data => data.json())
.then(user => {
dispatch(authSuccess(user));
})
.catch(error => dispatch(authFail(error)));
}
The tasks component
import React, {Component} from 'react';
import { connect } from 'react-redux';
import { Loading } from './LoadingComponent';
class Tasks extends Component {
constructor(props) {
super(props);
}
render() {
if(this.props.isLoading) {
<Loading />
} else {
return(<h1>Yes</h1>)
}
}
}
const mapStateToProps = state =>{
return {
isLoading: state.isLoading // Always get undefined
}
}
export default connect(mapStateToProps)(Tasks);
My useEffect code looks like this:
useEffect(() => {
if (user) {
setBalance(user.user_balance);
console.log("user.user_balance");
console.log(user.user_balance);
}
}, [user]);
Full code : https://pastebin.com/CP6sLNQZ
The useEffect is supposed to get triggered every time user (user_balance) gets updated in the database but it is not getting triggered. User is a props and it is passed from redux to the component.
The action for updating the balance is here:
import axios from "axios";
import { returnErrors } from "./errorActions";
import { UPDATE_BALANCE_SUCCESS } from "./types";
//update balance
export const updateBalance = ({ email, user_balance }) => (dispatch) => {
// Headers
const config = {
headers: {
"Content-Type": "application/json",
},
};
// Request body
const body = JSON.stringify({ email, user_balance });
axios
.post("/api/users/updatebalance", body, config)
.then((res) =>
dispatch({
type: UPDATE_BALANCE_SUCCESS,
payload: { email, user_balance },
})
)
.catch((err) =>
dispatch(returnErrors(err.response.data, err.response.status))
);
};
The reducer:
import { UPDATE_BALANCE_SUCCESS } from "../actions/types";
const initalState = {
email: null,
user_balance: null,
};
export default function (state = initialState, action) {
switch (action.type) {
case UPDATE_BALANCE_SUCCESS:
return {
...state,
email: action.payload.email,
user_balance: action.payload.user_balance,
};
}
}
And the end-point:
// #route POST api/users/updatebalance
// #description Update user balance
// #access Public
router.post("/updatebalance", (req, res) => {
const { email, user_balance } = req.body;
User.findOneAndUpdate(
{ email },
{ $inc: { user_balance: user_balance } },
function (err, result) {
if (err) {
res.send(err);
} else {
res.send(result);
}
}
);
});
Also where auth comes from:
This is the auth reducer: https://pastebin.com/upHdvtiF
These are the actions: https://pastebin.com/Ajp7S1Yi
And this is the end point: https://pastebin.com/NwCHCitY
I got a log in and register page and once a user gets registered auth gets created. In the actions link you can see the login and register action.
I think you have to add the user layer
const initalState = {
user: {
email: null,
user_balance: null,
}
};
and the reducer
export default function (state = initialState, action) {
switch (action.type) {
case UPDATE_BALANCE_SUCCESS:
return {
...state,
user: {
...state.user,
email: action.payload.email,
user_balance: action.payload.user_balance,
}
};
}
}
In my React app I am working in user login. My goal is to show current user's username when the user is logged in. I'm fetching the user data in redux actions and, as I followed some tutorials, I need to get jwt token coming from backend in fetch function. In login Fetch function I'm trying to get and save the token(see fetching function), but it shows undefined in devtools/localStorage. This is how InitialState updates in LoginSuccess in Reducers.
state
{user: {…}, loading: true, error: "", isAuthenticated: false, users: {…}}
error: ""
isAuthenticated: false
loading: true
user: {user: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dnZWRVc…xMTB9.hNsYTKGYIFRsPXw66AhB1o0EXyyfgfRTzOFzqBfjaTg"}
users: {user: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dnZWRVc…xMTB9.hNsYTKGYIFRsPXw66AhB1o0EXyyfgfRTzOFzqBfjaTg"}
__proto__: Object
I don't know how to get access to the current logged in user data: username or firstName for instanse.
Any help will be appreciated.
Actions
import axios from 'axios'
import { Dispatch } from 'redux'
import {
FETCH_USER_REQUEST,
UserActions,
User,
LOGIN_USER_SUCCESS,
FETCH_LOGIN_FAILURE,
LOGOUT,
} from '../../types/UserType'
export const fetchUserRequest = () => {
return {
type: FETCH_USER_REQUEST,
}
}
export const fetchLoginFailure = (error: UserActions) => {
return {
type: FETCH_LOGIN_FAILURE,
payload: error,
}
}
export function logout(): UserActions {
return {
type: LOGOUT,
}
}
export function loginSuccess(user: User): UserActions {
return {
type: LOGIN_USER_SUCCESS,
payload: {
user,
},
}
}
export const login = ({ email, password }: any) => {
return (dispatch: Dispatch) => {
dispatch(fetchUserRequest())
axios
.post('http://localhost:8000/logIn', {
email: email,
password: password,
})
.then((response) => {
const users = response.data
dispatch(loginSuccess(users))
localStorage.setItem('jwt', users.auth_token)
console.log('users', users) // undefined
})
.catch((error) => {
dispatch(fetchLoginFailure(error.message))
})
}
}
Reducer
import {
LOGIN_USER_SUCCESS,
UserActions,
UserState,
LOGOUT,
} from '../../types/UserType'
const initialState: UserState = {
user: {},
loading: false,
error: '',
isAuthenticated: false,
}
const UserReducer = (state = initialState, action: UserActions) => {
switch (action.type) {
case LOGIN_USER_SUCCESS:
console.log('state', state) // initialState update see above
return {
...state,
loading: false,
user: action.payload,
users: action.payload,
isAuthenticated: true,
error: '',
}
case LOGOUT:
return {
...state,
isAuthenticated: false,
user: null,
users: [],
}
default:
return state
}
}
export default UserReducer
And I assume I am going to show user userName or firstName in logout component
import React from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { Link } from 'react-router-dom'
import { Icon, Button } from 'semantic-ui-react'
import { logout } from '../../../redux/User/UserActions'
import { AppState } from '../../../types'
function Logout() {
const dispatch = useDispatch()
const user = useSelector((state: AppState) => state.user.user)
console.log('user', user)
const logoutOnClick = () => {
dispatch(logout())
localStorage.clear()
}
return (
<Button
color="black"
as={Link}
to="Login"
name="logout"
onClick={logoutOnClick}
>
<Icon name="sign out"> </Icon>Logout
</Button>
)
}
export default Logout
You save your logged-in data to localStorage like auth_token you did and clear in logout function.
axios
.post('http://localhost:8000/logIn', {
email: email,
password: password,
})
.then((response) => {
const users = response.data
dispatch(loginSuccess(users))
localStorage.setItem('jwt', users.auth_token)
localStorage.setItem('user', JSON.stringify(users))
console.log('users', users) // undefined
})
.catch((error) => {
dispatch(fetchLoginFailure(error.message))
})
and access inside your logout component or wherever you need that
let userDetails = JSON.parse(localStorage.getItem('user'));
and clear it inside logout function
const logoutOnClick = () => {
dispatch(logout())
localStorage.clear() // already clearing
}
I am a beginner in React.js. So, I am using theme from keenthemes. And it uses redux-persist and redux-saga for authentication with axios mock samples. It's original store initialState (persisted) is like this:
const initialAuthState = {
user: undefined,
authToken: undefined
};
But I want to implement authentication in my own style. So I changed the store into this format:
const initialAuthState= {
user: {
id: undefined,
username: undefined,
fullname: undefined,
email: undefined,
pic: undefined
},
authToken: undefined,
isAuthorized: false,
error: undefined
}
Then, I implemented some other codes required for authentication such as API calls, add some more actions, reducers, etc. After that, I ran the project and I noticed that the store remains still like the original.
Store
So, I searched the reasons and ways to solve that case, and tried to add migrations into persistconfig to inform the change of store structure. But the problem still remains. What should I do to change the store structure into the one that I want?
Migrations and PersistConfig from auth.duck.js:
const migrations = {
2: (state) => {
return {
...state,
user: {
id: undefined,
username: undefined,
fullname: undefined,
email: undefined,
pic: undefined
},
authToken: undefined,
isAuthorized: false,
error: undefined
}
}
}
const persistConfig = {
storage,
version: 2,
key: "demo1-auth",
whitelist: ['user', 'authToken', 'isAuthorized'],
migrate: createMigrate(migrations, { debug: true })
}
Reducer from auth.duck.js:
export const reducer = persistReducer(
// { storage, key: "demo1-auth", whitelist: ['user', 'authToken', 'isAuthorized']/*["user", "authToken"]*/ },
persistConfig,
(state = initialAuthState, action) => {
switch (action.type) {
// case actionTypes.Login: {
// return {...state, error: ""}
// }
case actionTypes.LOGIN_SUCCESS: {
//const { data } = action.payload;
//return action.payload.data//data//{...state, data}
return {...state, user: action.payload.data, authToken: action.payload.authToken, isAuthorized: true}
}
case actionTypes.LOGIN_FAIL: {
return {...state, error: action.payload.error}
}
// case actionTypes.register: {
// return {...state, error: ""}
// }
case actionTypes.REGISTER_SUCCESS: {
//const { data } = action.payload;
//return action.payload.data//data
return {...state, user: action.payload.data}
}
case actionTypes.REGISTER_FAIL: {
return {...state, error: action.payload.error}
}
case actionTypes.Logout: {
routerHelpers.forgotLastLocation();
logout(action.payload.id)
return iniState;
}
default:
return state;
}
}
);
Actions from auth.duck.js:
export const actions = {
login: (email, password) => ({
type: actionTypes.Login,
//payload: { email, password }
payload: { email: email, password: password }
}),
doLoginSuccess: (data) => ({
type: actionTypes.LOGIN_SUCCESS,
payload: {data: data}
}),
doLoginFail: (error) => ({
type: actionTypes.LOGIN_FAIL,
payload: {error: error}
//payload: error
}),
register: (username, fullname, email, password) => ({
type: actionTypes.Register,
//payload: { email, password }
payload: { username: username, fullname: fullname, email: email, password: password }
}),
doRegisterSuccess: (data) => ({
type: actionTypes.REGISTER_SUCCESS,
// payload: {data: data}
payload: {data: data}
//payload: data
}),
doRegisterFail: (error) => ({
type: actionTypes.REGISTER_FAIL,
payload: {error: error}
//payload: error
}),
logout: (id) => ({
type: actionTypes.Logout,
payload: { id: id}
})
};
Saga from auth.duck.js:
export function* saga() {
yield takeLatest( actionTypes.Login, function* loginSaga(action) {
// const {email, password} = action
const {email, password} = action.payload
// const payload = {email, password}
let data;
try {
// data = login(email, password)
/* data = yield call (login, payload)*/ data = yield call (login, email, password)
// data = {...data, isAuthorized: true, error: undefined}
console.log("Data in takelatest login in auth.duck: ", data)
yield put(actions.doLoginSuccess(data))
}
catch (error) {
console.log("Login axios post error is!: ", error)
yield put(actions.doLoginFail(error))
}
});
yield takeLatest(actionTypes.Register, function* registerSaga(action) {
// const {username, fullname, email, password} = action
const {username, fullname, email, password} = action.payload
// const payload = {username, fullname, email, password}
let data
try {
// data = register(username, fullname, email, password)
data = yield call (register, username, fullname, email, password)
// data = {...data, isAuthorized: false, error: undefined}
console.log("Data in takelatest register in auth.duck: ", data)
yield put(actions.doRegisterSuccess(data));
}
catch (error) {
console.log("Login axios post error is!: ", error)
yield put(actions.doRegisterFail(error));
}
});
rootReducer and rootSaga from rootDuck.js:
import { all } from "redux-saga/effects";
import { combineReducers } from "redux";
import * as auth from "./ducks/auth.duck";
import { metronic } from "../../_metronic";
import * as candi from "./ducks/candidateForm.duck";
export const rootReducer = combineReducers({
auth: auth.reducer,
i18n: metronic.i18n.reducer,
builder: metronic.builder.reducer,
candidateForm: candi.reducer
});
export function* rootSaga() {
yield all([auth.saga()]);
}
store.js:
import { applyMiddleware, compose, createStore } from "redux";
import createSagaMiddleware from "redux-saga";
import { persistStore } from "redux-persist";
import { rootReducer, rootSaga } from "./rootDuck";
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const sagaMiddleware = createSagaMiddleware();
const store = createStore(
rootReducer,
composeEnhancers(applyMiddleware(sagaMiddleware))
);
export const persistor = persistStore(store);
sagaMiddleware.run(rootSaga);
export default store;