Async API request axios and redux freeze app in react - reactjs

I'm trying to make an asynchronous request of an API.
In the meantime I am waiting for a response from it, starts preloader but at a certain moment it freeze. The request, I do it with axios and redux. What am I doing wrong?
import axios from "axios";
export const getPosts = () => {
return async (dispatch:any) => {
try {
dispatch({ type: 'GET_POSTS_BEGIN' });
const resp = await axios.get('MYAPI')
.then((resp) => {
dispatch({
type: 'GET_POSTS_SUCCESS',
posts: resp.data
})
})
} catch (err) {
console.error(err);
}
};
}

Related

How to get the response data by using react-query useMutation and axios post method?

I'm trying to get the data from a axios post methed.
I can get it by only using axios.
I cannot figure out why using the react-query useMutation console log the response data is undefined.
api/index.js
export const postCreateMeetingId = async (token) => {
await axios.post('http://localhost:3001/create-meeting/', {token:`${token}`}, {
headers: {
"Content-Type": "application/json",
authorization: `${token}`,
},
})
.then((res) => {
console.log(res.data) //successfully got the data here
return res.data
})
}
pages/meetingRoom.js
var token='my token is here'
export default function MeetingRoom(){
const {mutate, data} = useMutation(postCreateMeetingId, {
onSuccess: async (res) => {
console.log(res) //undefined
console.log(data) //undefined
}
})
const getMeetingAndToken = async () => {
return mutate(token)
}
return(
<div>
<button onClick={getMeetingAndToken}>get</button>
</div>
);
}
I wish to know how to get the response data by using useMutation so that I could throw this data to another post api.

after logging in my 2nd action is not getting dispatch after login success action

This is my auth.js action file where i have created loginUser and loadUser action. Inside loginUser action i have called loadUser() action. But the action loadUser is not being activated after LOGIN_SUCCESS action type.
export const loadUser = () => async (dispatch) => {
if (localStorage.token) {
setAuthToken(localStorage.token);
}
try {
const res = await axios.get('/api/auth');
dispatch({
type: USER_LOADED,
payload: res.data,
});
} catch (err) {
dispatch({
type: AUTH_ERROR,
});
}
};
export const loginUser = (email, password) => async (dispatch) => {
const config = {
headers: {
'Content-Type': 'application/json',
},
};
const body = JSON.stringify({
email,
password,
});
try {
const res = await axios.post('/api/auth', body, config);
dispatch({
type: LOGIN_SUCCESS,
payload: res.data,
});
dispatch(loadUser())
} catch (err) {
const error = err.response.data.msg;
if (error) {
dispatch(setAlert(error, 'danger'));
}
dispatch({
type: LOGIN_FAILED,
});
}
};
i tried so much to figure out the error but i dont know what is interfering with the action due to that only the first action is activated. Please help me. Thanks.
If you're just going to use it for the second action, then you don't need to export loadUser() method.
Just have it be a method in that file and then call it after the dispatch
...
dispatch({
type: LOGIN_SUCCESS,
payload: res.data,
});
loadUser();
...

resolving race condition on API call

I'm having a problem that seems to be due to an async call. I have an action that makes an API call and pushes to a Dashboard page. That API call also updates state.account.id based on the response it gives back:
const submitLogin = e => {
e.preventDefault();
props.loginAndGetAccount(credentials);
props.history.push('/protected');
e.target.reset();
}
loginAndGetAccount is coming from this action:
export const loginAndGetAccount = credentials => dispatch => {
dispatch({ type: GET_ACCOUNT_START })
axios
.post('https://foodtrucktrackr.herokuapp.com/api/auth/login/operators', credentials)
.then(res => {
console.log(res);
dispatch({ type: GET_ACCOUNT_SUCCESS, payload: res.data.id })
localStorage.setItem("token", res.data.token)
})
.catch(err => console.log(err));
}
On the Dashboard page, I have useEffect set up to make another API call dynamically based on the value held in state.account.id. However, it seems the first API call is pushing to the Dashboard page before the response comes back and updates state.account.id. Therefore, when the second API call is made there, it's passing state.account.id to that dynamic API call as undefined, which, of course, results in a failed call. How can I resolve this?
Here's what's happening:
const Dashboard = props => {
const [accountInfo, setAccountInfo] = useState({});
useEffect(() => {
console.log(props.accountId);
axiosWithAuth()
.get(`/operator/${props.accountId}`)
.then(res => {
console.log(res);
})
.catch(err => console.log(err));
}, [])
return (
<div>
<h1>This is the Dashboard component</h1>
</div>
)
}
const mapStateToProps = state => {
return {
accountId: state.account.id
}
}
export default connect(mapStateToProps, {})(Dashboard);
The root of the problem is that you are making a request here, but not
export const loginAndGetAccount = credentials => dispatch => {
dispatch({ type: GET_ACCOUNT_START })
axios
.post('https://foodtrucktrackr.herokuapp.com/api/auth/login/operators', credentials)
.then(res => {
console.log(res);
dispatch({ type: GET_ACCOUNT_SUCCESS, payload: res.data.id })
localStorage.setItem("token", res.data.token)
})
.catch(err => console.log(err));
}
waiting for it to complete here before you navigate to the next page
const submitLogin = e => {
e.preventDefault();
props.loginAndGetAccount(credentials);
props.history.push('/protected');
e.target.reset();
}
the quickest way to fix this is to returnt the promise from loginAndGetAccount and then props.history.push in the resolution of that promise...
like this:
export const loginAndGetAccount = credentials => dispatch => {
dispatch({ type: GET_ACCOUNT_START })
// return the promise here
return axios
.post('https://foodtrucktrackr.herokuapp.com/api/auth/login/operators', credentials)
.then(res => {
console.log(res);
dispatch({ type: GET_ACCOUNT_SUCCESS, payload: res.data.id })
localStorage.setItem("token", res.data.token)
})
.catch(err => console.log(err));
}
...
const submitLogin = e => {
e.preventDefault();
props.loginAndGetAccount(credentials)
.then(() => {
// so that you can push to history when it resolves (the request completes)
props.history.push('/protected');
e.target.reset();
}
.catch(e => {
// handle the error here with some hot logic
})
}

Axios interceptor does not redirect browser in a React app

I have a Redux/React application with an OAuth2 proxy. When the proxy gives a 401 response, the user needs to be redirected to an authentication page. Here is the basic idea using axios and interceptors.
import axios from 'axios'
export const axiosApi = axios.create({
baseURL: '/proxy/api',
})
axiosApi.interceptors.response.use(response => {
// Intercept successful response data
return response
}, error => {
if (error.response && error.response.status === 401) {
// Redirect when not authenticated
window.location.href = '/proxy/authorize'
}
return Promise.reject(error);
})
This is what the Redux actions that consume the axiosApi look like:
export const fetchUsers = () => dispatch =>
new Promise((resolve, reject) => {
axiosApi.get(`users`)
.then(res => {
dispatch(fetchUsersData(res.data))
resolve(res)
})
.catch(err => {
reject(err)
})
})
The problem is that window.location.href = '/proxy/authorize' does not actually redirect the browser. Is this because react-router(V5) is used?

Fetching data using API in react.js

I am trying to fetch data using API in react.js. My code is like below
import Axios from 'axios';
export const getCountry = () => dispatch => {
return Axios.get('http://treeoverflow.com/api/country/listing/true/111111111111222222222222333333333333444444444444', { crossdomain: true })
.then(response => {
console.log(response.data);
var countryData = response.data;
dispatch({
type: 'getCountries',
payload: countryData
});
})
.catch(function(error) {
console.log('hello');
dispatch({
type: 'getCountryError',
payload: error
});
});
};
export default { getCountry };
I getting below view in Network tab.
But I am not getting result. Is there any issue in this URL 'http://treeoverflow.com/api/country/listing/true/111111111111222222222222333333333333444444444444' ?

Resources