0

I am using React as a frontend and consuming my REST Api which is built in django-rest-framework. I am using simplejwt for token generation and authentication. Upon calling my token endpoints, I receive the tokens and I want to store the user information along the tokens inside my redux store, but I am unable to do that for some reason. I get "undefined" when I try accessing my store for user information.

This is my Login.js

function Login() {

    const dispatcher = useDispatch();
    
    const [login, setlogin] = useState({
        username: '',
        password:'',
    })
    
    return (
            <div className="col-8">

                <div class="form-group">
                    <label for="username">Username</label>
                    <input 
                        onChange={ (e) => setlogin( {...login, username:e.target.value} )} 
                        type="text" 
                        class="form-control" 
                        id="username" 
                        aria-describedby="usernameHelp"
                        value={login.username}>

                        </input>
                    <small id="usernameHelp" className="form-text text-muted">We'll never share your email with anyone else.</small>
                </div>

                <div class="form-group">
                    <label for="password">Password</label>
                    <input 
                        onChange={ (e) => setlogin( {...login, password:e.target.value} )}    
                        type="password" 
                        className="form-control" 
                        id="password"
                        value={login.password}>
                        </input>
                </div>

                <button 
                    class="btn btn-primary"
                    onClick={()=>{dispatcher(login_request(login))}}>Submit
                </button>

            </div>
    )
}

export default Login

This is my authActions.js

import {
    LOGIN,
    LOGOUT
} from './authTypes'

import axios from 'axios';

// called by login_request
export const login = (data) => {
    console.log('login action called with data :', data)
    return {
        type: LOGIN,
        payload: data,
    }
}

export const logout = () => {
    return{
        type: LOGOUT,
    }
}

// called in Login.js with date = { username, password }
export const login_request = (data) => {
    var userInfo = {}
    return(dispatch) => {
        axios.post('http://127.0.0.1:8000/api/token/',{
            'username': data['username'],
            'password': data['password'],
        })
        .then(res => {
            
            userInfo['username'] = res.data['username']
            userInfo['first_name'] = res.data['first_name']
            userInfo['last_name'] = res.data['last_name']
            userInfo['groups'] = res.data['groups']
            let config = {
                headers: {
                    // 'Access-Control-Request-Headers' : '*',
                    'Authorization': 'Bearer' + ' ' + res.data['access']
                }
            }
            axios.post('http://127.0.0.1:8000/api/token/refresh/',{
                'refresh':res.data['refresh']
            }, config)
            .then(res => {
                userInfo['access'] = res.data['access']
            }).catch(err => console.log(err))

        }).catch(err => console.log(err))
        dispatch(login(userInfo))
    }
}

And here is my authReducer.js


import {
    LOGIN,
    LOGOUT
} from './authTypes'

const reducer = (state={}, action) => {

    switch(action.type){

        case LOGIN:
            return {...state, 
                username: action.payload['username'],
                first_name: action.payload['first_name'],
                last_name: action.payload['last_name'],
                groups: action.payload['groups'],
                access: action.payload['access'],
            }

        case LOGOUT:
            return state
            
        default:
            return state

    }
}

export default reducer

Store.js

import { createStore, applyMiddleware, compose } from 'redux'
import thunk from 'redux-thunk'
import logger from 'redux-logger'

import rootReducer from './index';
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
    rootReducer,
    composeEnhancers(applyMiddleware(thunk, logger)) 
    );

export default store;
Usama Nadeem
  • 75
  • 3
  • 10
  • When you call `dispatch(login(userInfo))` your requests are not finished yet. – Yury Tarabanko Nov 13 '20 at 19:31
  • But I am receiving response when making request and I can console.log it too. When I console.log the data right before it is being sent to the action login (the userInfo) the data exists there as well. – Usama Nadeem Nov 13 '20 at 20:20
  • `console.log` might be deceptive. It doesn't snapshot data. But if you do say `console.log(JSON.stringify(data))` you will see that the object is empty when you call the action. Also if you add additional logs to `then` handlers you will notice that they are executed way after your action creator. – Yury Tarabanko Nov 13 '20 at 20:59
  • How would I know when the request has finished its task? – Usama Nadeem Nov 14 '20 at 12:00
  • Well, you'd need to read the linked question to begin with. – Yury Tarabanko Nov 16 '20 at 10:34

0 Answers0