How to present API response with redux and react - reactjs

I am new to front-end. I use react and redux-form after I subbmit form on backend don't know how to handle response and present it with react. My response is simply only one number.
return function (dispatch, getState) {
dispatch({
type: CHANGE_ID_SUBMIT_DATA,
});
let reqBody = {
firstname: changeId.firstName
username: cnahgeId.userName,
};
return fetch(`${__REST_HOST__}/test/api/change/id`, {
credentials: 'include',
method: 'post',
headers: {
'Accept': 'application/json;charset=UTF-8',
'Content-Type': 'application/json;charset=UTF-8',
},
body: JSON.stringify(reqBody),
}).then(
response => dispatch(receiveData(response)),
error => dispatch({
type: CHANGE_ID_RESPONSE_ERR_DATA,
error
})
);
};
}
function receiveData(resp) {
console.log(resp.text());
return resp.text().then(response => dispatch({
type: CHANGE_ID_RESPONSE_DATA,
newId: response,
receivedAt: moment(Date.now())
}));
}```

Related

Make Redux thunk calls synchronous for refreshing tokens

Integrated redux with thunk middleware. On expiry of access token, refresh token api is called and on its success the first api which was not successful due to expired token is recalled again.
The refresh token api is being called and returned because it is async. and the edit api is called right away before the response of refresh token success. How do i make it synchronous so as to call the api only after the response of refresh token is received
export function editClothDetails(data, id) {
return function(dispatch, getState) {
dispatch({ type: actions.EDIT_CLOTH_REQUEST });
fetch(BASE_URL + EDIT_CLOTH_URL + `/${id}`, {
method: "PUT",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + getState().Auth.accessToken
},
body: JSON.stringify({ ...data })
})
.then(result => checkHttpStatus(result))
.then(result => checkForError(result))
.then(jsonResponse => {
dispatch({
type: actions.EDIT_CLOTH_SUCCESS,
payload: jsonResponse
});
})
.catch((error) => {
if(error.message === "Invalid token") {
//what should be the right way to make these dispatches synchronous
dispatch(refreshToken());
dispatch(editClothDetails(data, id)); //setTimeout(()=> dispatch(editClothDetails(data, id)), 100);
}
console.error("There is an error in editing cloth details !! " + error.message);
dispatch({
type: actions.EDIT_CLOTH_FAILED,
payload: error.message
});
});
};
}
export function refreshToken() {
return (dispatch, getState) => {
dispatch({ type: actions.REFRESH_TOKEN_REQUEST });
fetch(BASE_URL + '/token', {
method: "GET",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'authorization': 'Bearer ' + getState().Auth.refreshToken
},
})
.then(result => checkHttpStatus(result))
.then(result => checkForError(result))
.then(jsonResponse => {
storeLocally(constants.APP_NAME, jsonResponse);
dispatch({
type: actions.REFRESH_TOKEN_REQUEST_SUCCESS,
payload: jsonResponse
});
})
.catch((err) => {
console.error("There is an error refreshing token !!" + err.message);
dispatch({
type: actions.REFRESH_TOKEN_REQUEST_FAILED,
payload: err.message
});
});
};
}
You have to use async-await here ...
export function editClothDetails(data, id) {
return async function(dispatch, getState) { // -> see here
.catch((error) => {
if(error.message === "Invalid token") {
await dispatch(refreshToken()); //--> see here
dispatch(editClothDetails(data, id));
}
// your other code
};
}
export async function refreshToken() {. /// ---> see here
return async (dispatch, getState) => {
dispatch({ type: actions.REFRESH_TOKEN_REQUEST });
/// your other code
};
}

Making Two API calls in react using axios

I am making an app where I send and receive data from one API. Once I get this data I want to make another call to the some other API sending this data to this second API and receiving data from this second API.
export const uploadImage = (data) => (dispatch) => {
dispatch({ type: UPLOAD_IMAGE });
axios({
method: 'post',
url: 'http://3.14.136.182:80/predict',
data: data,
"mimeType": "multipart/form-data",
headers: {
'content-type': 'multipart/form-data'
},
timeout: 20000
})
.then((response) => {
dispatch({ type: UPLOAD_IMAGE_SUCCESS, payload: response.data });
data = response.data;
axios({
method: 'post',
url: '3.14.136.182:8005/finalResult',
data: data,
"mimeType": "multipart/form-data",
headers: {
'content-type': 'multipart/form-data'
},
timeout: 20000
})
.then((response) => {
dispatch({ type: UPLOAD_IMAGE_SUCCESS, payload: response.data});
console.log("Mehmood",response.data);
})
.catch((error) => {
dispatch({ type: UPLOAD_IMAGE_FAILURE });
})
})
.catch((error) => {
dispatch({ type: UPLOAD_IMAGE_FAILURE });
})
}
You are missing at one return statement in you first then block. (before axios). Also you are dispatching success two times.

Convert fetch actions to axios actions

I'm trying to update my actions to axios from fetch.
For example my current login looks like this:
export const login = (email, password) => {
return (dispatch) => {
dispatch({
type: 'CLEAR_MESSAGES'
});
return fetch('/login', {
method: 'post',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: email,
password: password
})
}).then((response) => {
if (response.ok) {
return response.json().then((json) => {
dispatch({
type: 'LOGIN_SUCCESS',
token: json.token,
user: json.user
});
cookie.save('token', json.token, { expires: moment().add(1, 'hour').toDate() });
browserHistory.push('/account');
});
} else {
return response.json().then((json) => {
dispatch({
type: 'LOGIN_FAILURE',
messages: Array.isArray(json) ? json : [json]
});
});
}
});
};
}
So far for the conversion to axios, I have this:
export const login = (email, password) => {
// const { email, password } = this.props;
(dispatch) => {
dispatch({
type: 'CLEAR_MESSAGES'
})
axios({
method: 'post',
url: '/login',
data: { email: email, password: password }
}).then((response) => {
dispatch({
type: 'LOGIN_SUCCESS',
token: json.token,
user: json.user
});
cookie.save('token', json.token, { expires: moment().add(1, 'hour').toDate() });
browserHistory.push('/account');
})
.catch(() => dispatch({
type: 'LOGIN_FAILURE',
messages: Array.isArray(json) ? json : [json]
})
)
}}
Its not working :( and I'm not sure what I'm doing wrong - not too familiar with axios.
I'm getting this error in Google Chrome console
I believe the error is cause you're calling a json variable that is not present in your updated code.
You need to access the data via response.data. When using fetch() it made sense to convert the response with response.json() and use a thenable to tap into that json, but with axios, you can reach into the response right away without any conversions.
export const login = (email, password) => {
return (dispatch) => {
dispatch({
type: 'CLEAR_MESSAGES'
})
axios.post("/login", {email, password}).then((response) => {
dispatch({
type: 'LOGIN_SUCCESS',
token: response.data.token,
user: response.data.user
});
cookie.save('token', json.token, { expires: moment().add(1, 'hour').toDate() });
browserHistory.push('/account');
})
.catch(() => dispatch({
type: 'LOGIN_FAILURE',
messages: Array.isArray(json) ? json : [json]
})
)

How to synchronize fetch method in redux action

I am wondering how I can sync my fetch method. I want to prevent rendering data in a component before a response is returned.
Here is my redux action with my fetch method:
export const FETCH_DATA_START = 'FETCH_DATA_START'
export const FETCH_DATA_SUCCESS = 'FETCH_DATA_SUCCESS'
export const FETCH_DATA_FAILED = 'FETCH_DATA_FAILED'
export const getData = () => {
return (dispatch) => {
dispatch({
type: FETCH_DATA_START
})
fetch(baseUrl, {
credentials: "include",
method: "GET",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
})
.then(res => res.json())
.then((res) => {
dispatch({
type: FETCH_DATA_SUCCESS,
payload: res
})
})
.catch((err) => {
console.log(err)
dispatch({
type: FETCH_DATA_FAILED,
payload: 'error'
})
})
}
}
A common practice in this case is to set a flag like isFetching to true, and then display a loading spinner in your JSX based on the status of this flag.
Then when you received data, you hide this spinner and show the data.

React-Native : How to get callback of api call in another class

I am calling a web service
Here is my code:
var result;
export function callPostApi(urlStr, params)
{
fetch(urlStr, {method: "POST", headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(params)})
.then((response) => response.json())
.then((responseData) => {
result = JSON.stringify(responseData)
})
.catch((error) => { console.error(error);
Alert.alert('Alert Title failure' + JSON.stringify(error))
})
.done();
return result
}
I am calling from here:
callapi(){
var dict = {
email: 'at#gmail.com',
password: '123456',
}
result = callPostApi('http://demo.com', dict)
}
Currently, it is calling in Async mode that we want but code is written below this method getting execute immediately after calling of above method
i want callback when result from sever has received so that i can execute code written below the above method is execute after receiving response from server.
You need to use Promises.
Change your callPostApi function to return a Promise, then you can chain additional then, catch and finally calls.
export function callPostApi(urlStr, params) {
return fetch(urlStr, {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(params)
})
.then((response) => response.json())
.then((responseData) => {
result = JSON.stringify(responseData)
})
.catch((error) => {
console.error(error);
Alert.alert('Alert Title failure' + JSON.stringify(error))
});
}
callapi() {
callPostApi('http://demo.com', {
email: 'at#gmail.com',
password: '123456',
})
.then((response) => {
// Continue your code here...
});
}

Resources