Search code examples
javascriptreactjsreduxreact-reduxredux-thunk

How to fix "undefined" issue in async call to dispatch in action creator of redux?


I'm making a react app, implementing authentication to get token for the provides credentials from the server using the API call. Do my approach is perfect to do this?

I'm using Django API for backend and reactJS for frontend also using thunk as a middleware with redux.

authAction.js

import {AUTH_USER} from "./types";

export const authUser = (username, password) =>
{
    return (dispatch) => {
        const data = {
            username: username,
            password: password
        }
        return fetch("http://127.0.0.1:8000/api/v1/login/auth/", {
            method: 'POST',
            body: JSON.stringify(data),
            headers: {'Content-Type': 'application/json'}
        })
            .then(results => results.json())
            .then(results => {
                dispatch({
                type: AUTH_USER,
                payload: results
            })
            }
            )
    }
}

authReducer.js

import {AUTH_USER} from "../actions/types";

const initialState = {
    errors: [],
    token : '',
}
export default function (state=initialState,action) {
    switch (action.type) {
        case AUTH_USER:
            return {
                ...state,
                token:action.payload.token,
                errors:action.payload.errors,
            }
        default:
            return state
    }
}

login function

login(e){
        e.preventDefault();
        if(this.state.username && this.state.password){
            console.log("Login");
            this.props.authUser(this.state.username,this.state.password)
                .then(res=>console.log(res)) // undefined
        }
}

I want to get the results to be printed on the console which is fetched from API or in the more explained way I want to return the fetched results from the call of action in the caller. i.e. token: any token


Solution

  • It doesn't work that way. When you perform the action, after the async call, you do a dispatch with the result and the result is added to the store through the reducer. You need to get the values from the store by connecting to the store.

    const mapStateToProps = ({
      token, errors
    }) => ({
      token,
      errors
    });
    
    connect(mapStateToProps, {authUser})(Login)
    

    You can access this in your component now using this.props.token & this.props.errors