Axios interceptors not adding headers on some requests in React Native, iOS only - react-native

I have an Axios instance:
const axiosInstance = axios.create({
baseURL: API_URL,
timeout: 5000,
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
});
axiosInstance.interceptors.request.use(async (config: any) => {
const accessToken = await getSecureValue('accessToken');
config.headers.Authorization = `Bearer ${accessToken}`;
return config;
});
And some API functions:
export const getProfile = async () => {
const response = await axiosInstance.get('/user/profile');
return response.data;
};
export const postContact = async (message: string) => {
await axiosInstance.post('/contact', { message });
};
A user can log in and it calls getProfile(), that all works.
But when I try the postContact:
const handleSendPress = async () => {
try {
await postContact(textInput);
} catch (error) {
console.log(error);
}
};
It comes back with an error from the server that the Authorization header is missing.
Adding a console.log() in the interceptor I can see that it is running before the request.
I'm running Android and iOS in emulators, and this only happens on iOS.
I'm very lost what this could be, since getProfile() works but postContact() doesn't and they both use the same Axios instance.

Related

seting auth token in react native not working

i am trying to set auth token in react native but it is not working.the api call to the url is woeking and data is saved to db but the token doesnot work
axios({
method: 'POST',
url: 'http://127.0.0.1:8000/api/register',
data: Data,
})
.then(function (response) {
console.log('working');
ReactSession.setStoreType('Bearer', response.data.token);
ReactSession.set('username', 'Meon');
})
.catch(error => {
alert(JSON.stringify(error.response.data));
});
}
i get this error
console.log(response); returns the following
I use AsyncStorage together with fetch to set mine and then when i want to use it , I also call AsyncStorage from '#react-native-async-storage/async-storage';
After setting the state like this,
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
I try to simulate a Login
To login looks like this :
FunctionLogin = async () => {
let item = {email, password};
fetch('http://192.168.1.101/api/auth/sign-in', {
method: 'POST',
mode: 'cors',
headers: {
'Accept': 'application/json',
'Content-type': 'application/json',
},
body: JSON.stringify(item),
})
.then(response => response.json())
.then(async (responseJson) => {
if (responseJson.message === 'OK') {
var token = responseJson.token;
await AsyncStorage.setItem('email', email);
await AsyncStorage.setItem('token', token);
navigation.replace('Dashboard');
} else {
alert(responseJson);
}
})
.catch(error => {
console.error(error);
});
}
To use it in any page, I use it like this , later i reference the function in useEffect
showdata = async () => {
let token = await AsyncStorage.getItem('token');
alert(token);
};
Suppose I want to get transaction list from my endpoint to display data I do it like this
getTransactionsList = async () => {
let token = await AsyncStorage.getItem('token');
let email = await AsyncStorage.getItem('email');
var url = 'https://192.168.1.101/api/user-data/get-transactionby-email/';
fetch(url + email, {
method: 'GET',
headers: {
'Content-type': 'application/json',
'Authorization': `Bearer ${token}`,
},
})
.then(response => response.json())
.then(responseJson => {
setTransaction_details(responseJson);
setLoading(false);
});
};
Then suppose i want to call it inside useEffect, I do like this
useEffect(() => {
getTransactionsList();
});
Thats what and how i do it and it works fine. If you also know how to use Redux, its still a good one as well.

How do I make this axios call inside my own API route?

This is my first time trying to make an API call to a third party while inside my own API route. The following code does not work because I get the error "Cannot use import statement outside a module." This code is called by a thunk at the front end.
If I can't import axios, what's an alternative?
EDIT: I got rid of the error by doing 'const axios = require('axios') but now the results I'm getting is undefined.
EDIT2: Resolved. Through use of the following:
router.get("/:zip", async (req, res, next) => {
try {
let data = [];
await axios
.get(`https://api.yelp.com/v3/businesses/search`, {
headers: {
Authorization: `Bearer ${process.env.SECRET_KEY_YELP}`,
},
params: {
location: req.params.zip,
// categories: "coffee",
},
})
.then((response) => {
data = response.data;
});
res.send(data);
} catch (err) {
next(err);
}
});
ORIGINAL CODE WITH ISSUE:
const router = require("express").Router();
module.exports = router;
import axios from "axios";
router.get("/:zip", async (req, res, next) => {
try {
//const restaurants = await Test.findAll({})
const result = await axios.get(
`https://api.yelp.com/v3/businesses/search?location=${req.params.zip}`,
{
headers: {
Authorization: `Bearer ${process.env.SECRET_KEY_YELP}`,
},
params: {
categories: "coffee",
},
}
).data;
res.send(result);
} catch (err) {
next(err);
}
});
Posted above. It needed a .then snippet.
let data = [];
await axios
.get(`https://api.yelp.com/v3/businesses/search`, {
headers: {
Authorization: `Bearer ${process.env.SECRET_KEY_YELP}`,
},
params: {
location: req.params.zip,
// categories: "coffee",
},
})
.then((response) => {
data = response.data;
});
res.send(data);

How to send axios reques in react native?

I'm new to React Native and I'm trying to send axios request to my backend but I'm stuck in it.
export const login = (email, password) => async dispatch => {
const config = {
headers: {
'Content-Type': 'application/json'
}
};
const body = JSON.stringify({ email, password });
const res = await axios.post(`http://localhost:8000/auth/jwt/create/`, body, config);
console.log('kk');
dispatch({
type: LOGIN_SUCCESS,
payload: res.data
});
dispatch(load_user());
};
when it tries to post request through axios it gives following error.
although I haved tried this in React JS and it's working perfectly.
please help me to solve this in react native
Per the React Native Networking Docs, React Native supports the fetch web API for sending requests. I advise you use fetch instead of axios as it has all of the same features without any added bloat and overhead. Here is a port of your code to use fetch:
export const login = (email, password) => async (dispatch) => {
const res = await fetch(`http://localhost:8000/auth/jwt/create/`, {
method: "POST", // this signnifies POST request type
body: JSON.stringify({ email, password }), // still including the body
headers: {
// apply the headers
"Content-Type": "application/json"
}
});
const data = await res.json(); // parses the body as a json object
console.log("kk");
dispatch({
type: LOGIN_SUCCESS,
payload: data
});
dispatch(load_user());
};
Try to use this way:
// define axios request
import axios from 'axios';
const request = axios.create({
baseURL: 'https://url.com/api/v1',
timeout: 20000,
});
request.interceptors.request.use(
config => {
// config.headers.Authorization = `Bearer ${token}`;
config.headers.Accept = 'Application/json';
return config;
},
error => {
//return Promise.reject(error);
console.log("interceptors.request: ", error);
return false;
},
);
request.interceptors.response.use(
response => {
if (response && response.data) {
return response.data;
}
return response;
},
error => {
console.log('Response error: ', error);
//throw error;
return false;
},
);
export default request;
Usage:
import request from '../';
export const getAPI = () => {
return request({
url: '/getData',
method: 'GET',
// ...
});
};
getAPI().then(response => {
//...
});

UseEffect to run a function and that function set hook from another file

So what I want to do is throw my APIs in one file. This way it makes my app way more reusable.
Problem is that I don't know how to do what I'm doing.
My parent file holds all the Hooks I need for data.
I am trying to get the Parent file to call the API, run the call to get the data, then that data then calls back and sets the hook in the parent.
Parent File
import { handleDepartments } from './API/API';
export default function App() {
const [departments, setDepartments] = useState([]);
useEffect(() => {
handleDepartments;
}, []);
The API file..
export const handleDepartments = async () => {
console.log('getting Departments');
const data = await axios
.get(`URI`, {
headers: {
Authorization: 'API_KEY',
Accept: 'application/json',
},
})
.then((response) => {
setDepartments(response.data.departments);
})
.catch((err) => {
console.log(err);
});
};
You're on the right track but its not a great idea to pass down a setState function into the api to update the parent component. Instead, its better practice to make the api call only return data, then the parent can decide how to deal with it.
Api:
export const handleDepartmentsApi = async () => {
await axios
.get(`URI`, {
headers: {
Authorization: 'API_KEY',
Accept: 'application/json',
},
})
.then((response) => {
return data;
})
.catch((err) => {
return err;
});
};
Parent:
export default function App() {
const [departments, setDepartments] = useState([]);
const getDepartments = async () => {
try {
const response = await handleDepartmentsApi();
setDepartments(response.data.departments)
} catch (err) {
//handle error or do whatever
}
}
useEffect(() => {
getDepartments();
}, []);
return (<></>)
}

How to use Async Storage Axios

Problem:
I have create react-native application.And there I am using AsyncStorage with axios in like this to handle my API calls.This is how that looks like.
import axios from "axios";
import { AsyncStorage } from "react-native";
// TODO: Replace this with actual JWT token from Keycloak
axios.defaults.headers.post["Content-Type"] = "application/json";
// Create axios instance for api calls
var instance = null;
export const setAuth = async () => {
const user = await AsyncStorage.getItem("jwt");
AsyncStorage.getItem("jwt").then(token => {
instance = axios.create({
baseURL: "",
timeout: 150000,
headers: {
Authorization: "Bearer " + token,
"Content-Type": "application/json"
}
});
instance.interceptors.response.use(
function(response) {
return response;
},
async function(error) {
if (error.response.status) {
return error;
}
}
);
});
};
export const Get = (route, data) => {
instance || setAuth();
return instance.get(
route,
data == null ? { data: {} } : { data: JSON.stringify(data) }
);
};
export const Post = (route, data) => {
instance || setAuth();
return instance.post(route, JSON.stringify(data));
};
export const Put = (route, data) => {
debugger;
instance || setAuth();
return instance.put(route, JSON.stringify(data));
};
export const AddAdmin = (route, data) => {};
Becuase of the asynchronus property of AsyncStorage it is not creating the axios instanceinstance = axios.create({.The problem is with after this line .So can someone help me with this.I do not have any idea to find out what is wrong with this. Thank you.
You can give a try to this.
export const setAuth = async () => {
const token = await AsyncStorage.getItem('jwt');
instance = axios.create({
baseURL: '',
timeout: 150000,
headers: {
Authorization: 'Bearer ' + token,
'Content-Type': 'application/json'
}
});
// remaining Code
};
export const Get = (route, data) => {
function getData(){
return instance.get(
route,
data == null ? { data: {} } : { data: JSON.stringify(data) }
)
}
if(instance) return getData()
return setAuth().then(getData)
}