3

I am using redux-thunk . Here, I have one login action. On that action I am calling an API which will give me some token, that I have to store in the state. Then immediately, after success of this action, I have to make another API request which will have this token in the header and will fetch more data. Based on this, I would like to redirect the user.

Login Action

import { generateToken } from '../APIs/login';
import HttpStatus from 'http-status-codes';
import { LOGIN_FAILED, LOGIN_SUCCESS } from '../constants/AppConstants';
import {  fetchUserJd } from './GetUserJd';
import history from '../history';

    export function fetchToken(bodyjson) {
        return (dispatch) => {
            getLoginDetails(dispatch, bodyjson);
        }
    }

    export function getLoginDetails(dispatch, bodyjson) {
        generateToken(bodyjson)
            .then((response) => {
                if (response.status === 200)
                    dispatch(sendToken(response.payload))
                else
                    dispatch(redirectUser(response.status));
            })
    }

    export function sendToken(data) {
        return {
            type: LOGIN_SUCCESS,
            data: data,
        }
    }

    export function redirectUser(data) {
        return {
            type: LOGIN_FAILED,
            data: data,
        }
    }

2nd Action

import { FETCHING_JOBDESCRIPTION_SUCCESS, FETCHING_DATA_FAILED,FETCHING_JOBS } from '../constants/AppConstants';
import { getUserJobs } from '../APIs/GetUserJd';
import history from '../history';

export function fetchUserJd(token) {
    console.log(token);
    return (dispatch) => {
        dispatch(fetchingJobDescription());
    }
};

export function getUserJd(dispatch, token) {
    getUserJobs(token)
        .then((response) => {
            if (response.status === 200)
                dispatch(sendUserJd(response.payload))
            else
                dispatch(fetchFailure(response.status));
        })
}

export function fetchFailure(data) {
    return {
        type: FETCHING_DATA_FAILED,
        data: data,
    }
}

export function sendUserJd(data) {
    return {
        type: FETCHING_JOBDESCRIPTION_SUCCESS,
        data: data,
    }
}

export function fetchingJobDescription() {
    return {
        type: FETCHING_JOBS
    }
}

Calling this from

handleClick(event) {
        event.preventDefault();
        var bodyJson = {
            "username": this.state.UserName,
            "password": this.state.password
        }
        this.props.fetchToken(bodyJson);
    }

How can I call that second action immediately after the success of the first request. ?

Tried way ->

componentWillReceiveProps(newProps) {
        console.log(newProps.token);
        if(newProps.token) {
            this.props.fetchUserJd(newProps.token);
        }
    }


export function sendUserJd(data) {
    if (data.data.length > 0) {
        history.push('/userJobs');
    } else {
        history.push('/createJob');
    }
    return {
        type: FETCHING_JOBDESCRIPTION_SUCCESS,
        data: data,
    }
}
ganesh kaspate
  • 667
  • 7
  • 20

1 Answers1

1

You can do without setting it to redux state. You need to return your success action call to get the token in component itself using promise .then and then call this.props.sendToken(token); which will actually set the data in state and follows your existing flow.

handleClick(event) {
        event.preventDefault();
        var bodyJson = {
            "username": this.state.UserName,
            "password": this.state.password
        }
        this.props.getLoginDetails(bodyJson).then((token) => {
           this.props.sendToken(token);
        });
    }

And in actions

const GET_LOGIN_DETAILS_SUCCESS = 'GET_LOGIN_DETAILS_SUCCESS';
export function getLoginDetailsSuccess(data) {
    return {
        type: GET_LOGIN_DETAILS_SUCCESS,
        data: data,
    }
}

    export function getLoginDetails(bodyjson) {
        generateToken(bodyjson)
            .then((response) => {
                if (response.status === 200)
                    return dispatch(getLoginDetailsSuccess(response.payload))
                else
                    dispatch(redirectUser(response.status));
            })
    }

Let me know if you have any questions or if you feel difficult to understand

Hemadri Dasari
  • 23,970
  • 25
  • 87
  • 133
  • Yes,But I need to store that token in the state, because I need to have that in almost.every component – ganesh kaspate Aug 17 '18 at 17:14
  • ok. The you normally in success action call set the token in redux state and get the token from state in your component in componentWillReceiveProps and check with this.props.token with nextProps.token and if they are not same then call this.props.sendToken(token); – Hemadri Dasari Aug 17 '18 at 17:18
  • Actually, what I have to do is I have to call two actions one after another and also want to dispatch that data. For e.g. when user try to login then I send one req that will validate and then will give me one token in response that I have to store in state. After this Immediately I have to call one more api that will give me some data if data is present then I have to redirect user to a diff view or else to diff virw. – ganesh kaspate Aug 17 '18 at 17:22
  • Even I am telling you the same you make an action call from your component in handleClick >> then in actions that action dispatches success action call with the token >> that success action call returns type and the token >> In reducer when that type matches you will set the token in the redux state using state.set or state.setIn >> now, you get the token in component where handleClick is defined >> you return that state as props using redux connect >> now, in componentWillReceiveProps you get the token which you pass it to this.props.sendToken(token);. Understood? – Hemadri Dasari Aug 17 '18 at 17:29
  • That's how you should do – Hemadri Dasari Aug 17 '18 at 17:30
  • So, You are considering here sendToken is a function that I want to call after the success of first ? – ganesh kaspate Aug 17 '18 at 17:39