Axios with Auth is not a valid axios instance - react-native

I'm trying to set Authorization headers on an axios post request using axios.create(). I have this in a file and when I try to import the function into my React Native component, I get the following error:
axiosWithAuth.default().post is not a function
below is my code for the function:
import axios from 'axios';
import {AsyncStorage} from 'react-native';
// import AsyncStorage from '#react-native-community/async-storage'
async function axiosWithAuth() {
const token = await AsyncStorage.getItem('userToken');
console.log('token from asyncstorage' , token);
return axios.create({headers : {'Content-Type': null, Authorization : token}})
}
export default axiosWithAuth;
and I'm using the function in the following React Native Component:
import axiosWithAuth from '../utils/axiosWithAuth';
const Recipe = (props) => {
const likeIt = () => {
console.log('like pressed');
console.log('props', props.recipe.id);
setLike(!like);
axiosWithAuth().post(`API_URL`,{})
.then(res => console.log('response from post like: ', res.data))
.catch(err => console.log('error in posting like', err.response))
}
return (
<Text>This is the Recipe Component </Text>
)
}

You used async with axiosWithAuth function. It is returning a Promise, not an instance of axios. You have to write it like this
(await axiosWithAuth()).post(`API_URL`,{})
.then(res => console.log('response from post like: ', res.data))
.catch(err => console.log('error in posting like', err.response))

Below is the code that worked. Create a variable and set it = await axiosWithAuth(). Then do a post request off of the variable. Below is the axiosWithAuth function definition:
import axios from 'axios';
import {AsyncStorage} from 'react-native';
async function axiosWithAuth() {
const userToken = await AsyncStorage.getItem('userToken');
console.log('userToken', userToken);
// return axios.create({headers : {'Content-Type': null, Authorization : userToken}})
return axios.create({headers : {Authorization : userToken}})
}
export default axiosWithAuth;
and below is the code that is using the axiosWithAuth function:
import axiosWithAuth from '../utils/axiosWithAuth';
const likeIt = async () => {
await setLike(!like);
console.log('liked?', like);
const axiosAuth = await axiosWithAuth();
console.log('axiosAuth', axiosAuth);
if (!like) {
axiosAuth.post(`https://url`,{})
.then(res => {
console.log('response from post like: ', res.data.message);
})
.catch(err => console.log('error in posting like', err.response))
} else {
axiosAuth.delete(`https://url`)
.then(res => console.log('res from unlike', res))
.catch(err => console.log('err from deleting like', err))
}
}

Related

ReactNative: AsyncStorage Problem : I can't retrieve Data the correctly

I am trying to use the AsyncStorage in my Project by Saving the token to the AsyncStorage by using setItem()
Action that response with token
import axios from 'axios';
import {URL, Config} from '../../service/Api';
import AsyncStorage from '#react-native-async-storage/async-storage';
export const checkSmsToLoginUser = value => async dispatch => {
dispatch({type: 'USER_LOGIN_REQUEST'});
try {
const {data} = await axios.post(`${URL}user/checkSMSCode`, value, Config);
console.log(data.token); // it consoles the token
await AsyncStorage.setItem('USER_TOKEN', data.token);
dispatch({type: 'USER_LOGIN_SUCCESS', payload: data?.token});
} catch (error) {
dispatch({type: 'USER_LOGIN_ERROR', payload: error});
}
};
and I dispatch the action in the component, then I try to get the the token from the the AsyncStorage by using getItem
const getData = async () => {
try {
const token = await AsyncStorage.getItem('USER_TOKEN');
return token, JSON.parse(token);
} catch (error) {
return error;
}
};
console.log(getData(), 'token From AsyncStorage');
but when I console the token that comes from the AsyncStorage, I have some sort of unhandled promise
any clue what's the problem or maybe solution?
This might help
function App() {
const getData = async () => {
try {
const token = await AsyncStorage.getItem('USER_TOKEN');
// Log here
console.log(JSON.parse(token), 'token From AsyncStorage');
} catch (error) {
return error;
}
};
useEffect(() => {
getData(); // call here
}, []);
return (
<View>
...
</View>
);
}
You are printing an async function without awaiting for it.
The code is correct, but the console log is not correct:
console.log(getData(), 'token From AsyncStorage'); // missing async logic
Insert the console log inside the getData function, or await for the response.
By Adding the getData() in UseEffect and handling the promise by using then().catch() worked for me
useEffect(() => {
getData()
.then(res => {
console.log(res, 'it worked');
setToken(res);
})
.catch(err => {
setError(err);
console.log(err);
});
}, []);

How do I send response object from my get request to the front end with Express and Axios?

I am trying to pull data from MongoDB to populate some timers in this app I'm building. However, I can't seem to send my response to the front end with Axios. Here is my route on the backend:
const express = require('express');
const router = express.Router();
const TimerModel = require('../models/Timer');
router.get('/', async (req, res) => {
try {
const timers = await TimerModel.find({});
console.log('Succesful get req', timers);
res.send(timers);
} catch (err) {
console.log(err.message);
res.status(500).send('Server Error');
}
});
module.exports = router;
My console.log in the try statement prints the correct data but I'm having issues with sending it to the front end. Here is the component:
import React, { useState, useEffect } from 'react';
import Timer from '../Timer/Timer';
import axios from 'axios';
import './Wrapper.css';
function Wrapper() {
//State effects
useEffect(() => {
axios
.get('/')
.then((res) => {
console.log(res);
console.log(res.data);
})
.catch((err) => {
console.log(err);
});
});
const handleChange = (event) => {
setTitle(event.target.value);
};
const addTimer = () => {
const timer = <Timer title={title} key={timers.length} />;
let allTimers = timers.slice();
allTimers.push(timer);
setTimers(allTimers);
setTitle('');
};
return (
//JSX Code
);
}
export default Wrapper;
In the axios call I make, I get this weird object when I run console.log(res) and I get my index.html for the res.data. Why don't I have access to the timers object I made with my backend request? Isn't it being sent when I run the command res.send(timers) in my route?
You need to add your API url in axios request. Currently, axios is taking url of your React website that is why your response have index.html file of React website.
useEffect(() => {
axios
.get('api_url/')
.then((res) => {
console.log(res);
console.log(res.data);
})
.catch((err) => {
console.log(err);
});
});
You can save the result in a state like
`````````````
`````````````
const [time, setTimer] = useState(null)
useEffect(() => {
axios.get('/').then(res => setTimer(res.data)
}, [])
`````````````
`````````````
and then use time vairable where you want

axios cancel is not working in react native redux

I am using axios for api call in react native application. I have redux for managing state in the application. I am trying to cancel the axios request when the component is unmounted but it is not cancelling.
import axiosMaker from '../../axios'
useEffect(() => {
const source = axios.CancelToken.source()
props.fetchFile(fileName, source.token)
return() => {
console.log('un mounting document view')
source.cancel()
}
},[])
//redux action
export const fetchFile = (location, token) => {
return async (dispatch) => {
dispatch(fetchFileRequest())
const config = {
path : location,
}
let axiosObj = await axiosMaker()
try{
axiosObj.post('download', config,
{
headers :{
'authorization' : `Bearer ${accessToken}`
}
},
{
cancelToken: token
}
)
.then(async response => {
console.log('doucment view success')
dispatch(fetchFileSuccess(response.data))
})
.catch(error => {
console.log('doucment view failure')
dispatch(fetchFileFailure(error))
})
} catch(error){
if(axiosObj.isCancel(error)){
console.log('request is canceled')
}
console.log('hello world')
}
}
}
What am I doing wrong here? How to cancel the axios call in redux?
I was sending accessToken and cancelToken separately. I sent it together.
axiosObj.post('download', config,
{
headers :{
'authorization' : `Bearer ${accessToken}`
},
cancelToken : token
}
)
and another changes is isCancel() function is available in the axios object itself not in the customize axios object. So, I imported the axios
import axios from 'axios'
and called isCancel function in this object, not in the axiosMaker object.
if(axios.isCancel(error)){
console.log('request is canceled')
}

Action Creator return undefined axios

Can successfully register the user using my action creator but it returns undefined. I think it's the way how am returning my dispatch
axiosInstance
import axios from 'axios';
import AsyncStorage from '#react-native-community/async-storage';
// import base url
import {API_URL} from '../constants';
const instance = axios.create({
baseURL: API_URL,
timeout: 2000,
});
instance.interceptors.request.use(
async(config) => {
const token = await AsyncStorage.getItem('token');
if(token) {
config.headers.Autherization = `${token}`;
}
return config;
},`enter code here`
(err) => {
return Promise.reject(err);
}
)
export default instance;
SignUP Action.
import axiosInstance from '../../api/axiosInstance';
import {REGISTER_USER_SUCCESS, REGISTER_USER_FAIL} from '../actionTypes/index';
const registerSuccess = (payload) => {
return{
type: REGISTER_USER_SUCCESS,
data: payload
}
};
const registerError = (payload) => {
return {
type: REGISTER_USER_FAIL,
data: payload
}
};
export const SignUp = (registerData) => async dispatch => {
axiosInstance.post('/users/register', registerData)
.then((response)=> {
dispatch(registerSuccess(response.data));
})
.catch((error) => {
dispatch(registerError(error));
});
}
Here is how am using my action creator .. the result is undefined . I want to have a check some that I can redirect the screen to another login screen or home screen
SignUP Submit function
dispatch(registerAction.SignUp(values))
.then( (result) => {
console.log('klhadsghaj',result.status);
if(result.success) {
try {
navData.navigation.navigate("Login");
}catch (err) {
console.log(err)
}
} else {
Alert.alert('Registration failed. Try Again')
}
})
.catch(err => console.log(err))

using axios in service object in React Native fails

I can't figure out why this does not work. I think it has to do with having a promise nested inside another promise:
I set up my api service object:
api.js
import axios from 'axios';
import apiConfig from './apiConfig';
import deviceStorage from '../services/deviceStorage.js';
export const get = (endpoint, payload = {}, headers = {}) => {
const jwt = deviceStorage.loadJWT
headers.Authorization = jwt
console.log("running..");
axios({
method: 'GET',
url: apiConfig.development.url + endpoint,
headers: headers,
data: payload,
}).then((response) => {
console.log('will return response..');
return response;
}).catch((error) => {
console.log('will return error..');
return error;
});
};
then I call it from a screen:
NotificationsScreen.js
import React from 'react';
import { View, ScrollView, Text, Button, StyleSheet } from 'react-native';
import axios from 'axios';
import Header from '../components/Header';
import NotificationCardSection from '../components/notificationsScreen/NotificationCardSection';
import NotificationCardList from '../components/notificationsScreen/NotificationCardList';
import { Loading } from '../components/common/';
import globalStyles from '../globalStyles';
import * as api from '../services/api'
export default class NotificationsScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: true,
notifications: [],
error: ''
};
}
componentDidMount() {
console.log("will get data from api");
api.get(
'/notifications'
).then((response) => {
console.log("got back data from api");
this.setState({
notifications: response.data.data,
loading: false
});
}).catch((error) => {
console.log("got error from api");
this.setState({
error: 'Error retrieving data',
loading: false
});
});
}
but i get an error:
TypeError: Cannot read property 'then' of undefined.
terminal shows 'running..' but does not show 'will return response...' or 'will return error' so they are not firing.
I assume it is because the api call has not finished yet, but since it is async, how can I make sure it HAS finished when calling it from the screen?
You are expecting a Promise to be returned from your get since you are using then and catch on it but you are just returning a response or an error.
Your get function should look like the below if you want to use .then with it:
export const get = (endpoint, payload = {}, headers = {}) => {
return new Promise((resolve, reject) => {
const jwt = deviceStorage.loadJWT
headers.Authorization = jwt
console.log("running..");
axios({
method: 'GET',
url: apiConfig.development.url + endpoint,
headers: headers,
data: payload,
})
.then((response) => {
console.log('will return response..');
resolve(response);
})
.catch((error) => {
console.log('will return error..');
reject(error);
});
});
};