Backend services are working correctly. I'm trying to set the header parameter. But I am making a mistake somewhere. I can't get a response.
Error appearing in console: Request failed with status code 417
How can I solve it?
PolicyService.js
const getAsosPaymentInfo = (getPolicyAccountInfoRequestDto) => {
return new Observable((observer) => { // <PaymentInfoResponseDto>
axiosInstance
.post(SERVICE_PATH + '/getAsosPaymentInfo', getPolicyAccountInfoRequestDto, {
headers: { 'sales-channel': 200008, 'agency-code': 10038, 'content-type': 'application/json' }
})
.then((response) => {
observer.next(response.data);
observer.complete();
})
.catch((err) => {
console.log(err);
});
});
};
policy-payment-info.js
const req = {
policyNumber: '1277976920',
renewalNumber: '01',
policyTypeExtCode: '800',
productTypeExtCode: '2000062'
};
useEffect(() => {
if (props.location.state.policy.isActive === true) {
PolicyService.getAsosPaymentInfo(req).subscribe(
(response) => {
console.log(response);
}
);
}
}, []);
Related
There is no issue on my server side. I tested my API on Postman and getting an HTTP 200 response. See the screenshot.
But when sending data using Axois POST, it can't validate my user data or not sending necessary token to server.
Here is my Axois post code:
const handleSubmit = (event) => {
event.preventDefault();
setHideButton(false)
const data = {
title: parent_product.title,
return {
size: variation.size,
// Add the rest of the variation fields here
};
})
};
console.log(data)
axios.defaults.withCredentials = true;
axios.post('http://127.0.0.1:8000/product/main_product', data, {
method: 'POST',
withCredentials: true,
})
.then(res => {
console.log(res);
console.log(res.data.var_list);
var var_list = res.data.var_list
var img_array = variations.map((data) => (data.images))
setHideButton(true)
if (res.status == 200) {
seterrormessage("")
async function sendPayload(id, images) {
try {
images.forEach((image) => {
const formData = new FormData();
formData.append('varitaion_image_id', id);
formData.append('files', image);
axios.post('http://localhost:8000/gallary_images/upload', formData, {
withCredentials: true
}).then((response) => {
console.log(response.data);
}).catch((error) => {
console.error(error);
});
});
} catch (error) {
console.error(error);
}
}
var_list.forEach((id, index) => {
sendPayload(id, img_array[index]);
});
}
})
.catch(error => {
console.log(error);
if (error.response && error.response.data && typeof error.response.data.detail === 'string') {
setHideButton(true);
setAxoisError(error.response.data.detail);
} else {
setAxoisError("");
}
setHideButton(true)
});
};
Here you see the network tab information:
I'm trying to store and get data that I fetch from an API. The user is supposed to get a token on the login screen, and the token will be shown in an Alert dialog on home screen when the user press a button. But the token is not shown in the Alert dialog. the token is shown after I reload(not refresh the app. I used Live Server extension) the screen three times.
Login.js
const _userLogin = () => {
fetch(URLs._login, {
method: "POST",
headers, body,
})
}).then((response) => response.json())
.then((result) => {
if(result.message !== "Unauthorized / Access Token Expired" && result.message !== "The given data was invalid."){
storeData(result.access_token, result.token_type);
navigation.navigate('HomeScreen');
} else {
Alert.alert("Error", result.message);
}
});
};
const storeData = async (accessToken, tokenType) => {
try {
await AsyncStorage.setItem('#access_token', accessToken);
await AsyncStorage.setItem('#token_type', tokenType);
await AsyncStorage.setItem('#user_auth', tokenType + " " + accessToken);
} catch (e) {
console.log(e);
}
}
Home.js [UPDATE]
const [inputs, setInputs] = React.useState({
userToken: '',
userPointsBalance: '',
expiringOn: '',
});
useEffect (() => {
_dashboard();
})
const getToken = async () => {
inputs.userToken = await AsyncStorage.getItem('#user_auth');
}
const _dashboard = () => {
getToken();
fetch(URLs._dashboard, {
method: "GET",
headers: {
'Authorization': inputs.userToken,
'Content-Type': 'application/json',
},
}).then((response) => response.json())
.then(async (result) => {
storeData(result.code, result.name, result.member_name, result.user_points_balance, result.expiring_on, result.status, result.token_id);
getData();
});
};
const storeData = async (code, name, memberName, userPointsBalance, expiringOn, status, tokenId) => {
try {
await AsyncStorage.setItem('#user_points_balance', userPointsBalance.toString());
await AsyncStorage.setItem('#expiring_on', expiringOn.toString());
} catch (e) {
console.log(e);
}
}
const getData = async () => {
const userPointsBalance = await AsyncStorage.getItem('#user_points_balance');
const expiringOn = await AsyncStorage.getItem('#expiring_on');
setInputs({userPointsBalance: userPointsBalance, expiringOn: expiringOn});
}
return (
<Text>{inputs.expiringOn}<Text>
)
i hope it works
.then(async(result) => {
if(result.message !== "Unauthorized / Access Token Expired" && result.message !== "The given data was invalid."){
await storeData(result.access_token, result.token_type)
.then(res=>
navigation.navigate('HomeScreen')
)
} else {
Alert.alert("Error", result.message);
}
});
I use in my react application redux saga. There i have a login form. With redux saga i try to handle the error when user login.
Bellow is my saga:
function* postLoginUserReq(user) {
const {name} = user.values.user;
try {
const data = yield call(() => {
return fetch("url", {
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: name,
}),
}).then(data => data.json()).then(response => {
userErrorLogIn(response.error) //here i check if appears an error
})
});
} catch (error) {
console.log(error);
}
}
Bellow is action creator:
export const userErrorLogIn = (error) => {
console.log(error) //the error message appears here
return {
type: USER_ERROR_LOGIN,
payload: error
};
};
Bellow is reducer:
case USER_ERROR_LOGIN: {
console.log(action.payload) //here the error message does not appears (why?)
return {
...state,
userIsLoggedError:action.payload,
}
}
Question: What could be the issue that i don't get the error in reducer?
You can use .catch for that -
function handleErrors(response) {
if (!response.ok) {
throw Error(response.statusText);
}
return response;
}
fetch("http://httpstat.us/500")
.then(handleErrors)
.then(response => console.log("ok") )
.catch(error => userErrorLogIn(error) );
https://www.tjvantoll.com/2015/09/13/fetch-and-errors/
I am working on login feature and have problem when refresh token.
When token expire making request to refresh token, remove the old token, and save the new token to AsyncStorage.
After login successfully have to function A and B. The function A is using the new token to make its request. the function B say that it need to refresh the token so make request to refresh token ( the request make successfully, token being refresh) but The token that request A is using now invalid - I think it happens due to asynchronous
This is my code that use to refresh token:
axiosInstance.interceptors.response.use(
function (response) {
return response;
},
async function (error) {
if (error.response.status === CODE_TOKEN_EXPIRED) {
try {
const token = await authenticationService.getRefreshToken();
const response = await authenticationService.refreshToken(token);
await authenticationService.removeToken();
await authenticationService.storeToken(response.data.params.access_token);
await authenticationService.storeRefreshToken(response.data.params.refresh_token);
error.config.headers.Authorization = 'Bearer ' + response.data.params.access_token;
error.response.config.headers['Authorization'] = 'Bearer ' + response.data.params.access_token;
return axiosInstance(error.config);
} catch (err) {
console.log(2, err);
await authenticationService.removeToken();
navigationService.navigate('LoginForm');
}
}
return Promise.reject(error);
}
);
Anyone know how to handle which asynchronous call for refresh token?
First would be for you to check if you are changing token to the correct axios instance. It is necessary to change Authorization header on error.response config as you did, but also for main axios instance (if you have one) like so: axios.defaults.headers.common["Authorization"] = "Bearer " + access_token;
If it is multiple parallel requests going on that could possibly need to be postponed after token is refreshed issue and answer gets complex, but check this gist with full refresh logic with axios.
I have implemented the same scenario in fetch API. you can also do this same in axios API. Try this to avoid interceptor concept.
Api.ts
export const api = ({ method, url, body, isProtected = true }) => {
return new Promise((resolve, reject) => {
const payload = {
method,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
}
};
if (body !== null) {
(payload as any).body = JSON.stringify(body);
}
/**
* "isProtected" is used for API call without authToken
*/
if (isProtected) {
AsyncStorage.getItem(ACCESS_TOKEN).then(accessKey => {
(payload.headers as any).Authorization = `Bearer ${accessKey}`;
fetch(url, payload)
.then((response: any) => {
/*
* 419 status denotes the timeout of authToken
*/
if (response.status == 419) {
// refresh token
AsyncStorage.getItem(REFRESH_TOKEN).then(refreshKey => {
const payloadRef = {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: 'Bearer ' + refreshKey
}
};
/*
* This call refresh the authToken using refreshing call to renew the authToken
*/
fetch(URL.baseUrl + "/refresh", payloadRef)
.then((response: any) => response.json())
.then(response => {
/*
* if refresh token expired. redirect to login page
*/
if (response.status !== codes.SUCCESS) {
if (!User.sessionOver) {
User.sessionOver = true;
Alert.alert(
'Alert',
'Session Timeout',
[
{
text: 'Get back to Login',
onPress: () => {
// get to Login page
}
}
],
{ cancelable: false }
);
}
} else if (response.status == codes.SUCCESS) {
/*
* If refresh token got refreshed and set it as authToken and retry the api call.
*/
AsyncStorage.setItem(ACCESS_TOKEN, response.payload.access_key).then(() => {
(payload.headers as any).Authorization = 'Bearer ' + response.payload.access_key;
fetch(url, payload)
.then(response => response.json())
.then(response => {
if (response.status == codes.SUCCESS) {
resolve(response);
}
})
.catch(error => {
reject(error);
});
});
}
});
});
} else {
resolve(response.json());
}
})
.catch(error => {
reject(error);
});
});
} else {
fetch(url, payload)
.then((response: any) => {
response = response.json();
resolve(response);
})
.catch(error => {
reject(error);
});
}
});
};
MovieService.ts
import { api } from '../services/api';
import { URL } from '../config/UrlConfig';
const getMovies = () => {
const method = 'GET';
const url = URL.baseUrl + '/v1/top/movies';
const body = null;
const isProtected = true;
return api({ method, url, body, isProtected });
};
export { getMovies };
Maybe it will helps - https://gist.github.com/ModPhoenix/f1070f1696faeae52edf6ee616d0c1eb
import axios from "axios";
import { settings } from "../settings";
import { authAPI } from ".";
const request = axios.create({
baseURL: settings.apiV1,
});
request.interceptors.request.use(
(config) => {
// Get token and add it to header "Authorization"
const token = authAPI.getAccessToken();
if (token) {
config.headers.Authorization = token;
}
return config;
},
(error) => Promise.reject(error)
);
let loop = 0;
let isRefreshing = false;
let subscribers = [];
function subscribeTokenRefresh(cb) {
subscribers.push(cb);
}
function onRrefreshed(token) {
subscribers.map((cb) => cb(token));
}
request.interceptors.response.use(undefined, (err) => {
const {
config,
response: { status },
} = err;
const originalRequest = config;
if (status === 401 && loop < 1) {
loop++;
if (!isRefreshing) {
isRefreshing = true;
authAPI.refreshToken().then((respaonse) => {
const { data } = respaonse;
isRefreshing = false;
onRrefreshed(data.access_token);
authAPI.setAccessToken(data.access_token);
authAPI.setRefreshToken(data.refresh_token);
subscribers = [];
});
}
return new Promise((resolve) => {
subscribeTokenRefresh((token) => {
originalRequest.headers.Authorization = `Bearer ${token}`;
resolve(axios(originalRequest));
});
});
}
return Promise.reject(err);
});
export default request;
I want to access this in the second then methode from the fetch.
But it keeps saying: TypeError: _this2.login is not a function
fbAuth() {
LoginManager.logInWithReadPermissions(['public_profile']).then(function(res) {
if (res.isCancelled) {
console.info('cancelled');
} else {
console.info('login success');
AccessToken.getCurrentAccessToken().then((data) => {
let req = new GraphRequest('/me', {
httpMethod: 'GET',
version: 'v2.5',
parameters: {
'fields': {
'string' : 'id,email,name'
}
}
}, (err, res) => {
const data = new FormData();
data.append('facebook_user_id', res.id);
data.append('email', res.email);
data.append('name', res.name);
fetch('xxxxxxxxxxx', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: data,
})
.then((response) => response.json())
.then((responseJson) => {
this.login(responseJson);
})
.catch((error) => {
console.error(error);
alert('Something went wrong. Please try again, if the problem persists contact the #lacarte service desk');
});
});
new GraphRequestManager().addRequest(req).start();
});
}
}, function(error) {
console.error(error);
});
}
Assuming that this should be the same this that also has the fbAuth method, you should use an arrow function declaration for the first promise as well:
LoginManager.logInWithReadPermissions(['public_profile']).then(res => {
...
});