Setting axios base url dynamically - reactjs

i am getting base url from asyncstorage and i want to set it as base url for axios instance.
currently iam following below code but it is not working
const axiosInstance = axios.create({
// baseURL: API_END_POINTS.BASE_URL+AsyncStorage.getItem('dealerNo'),
});
axiosInstance.defaults.timeout = 10000000;
axiosInstance.interceptors.request.use(
async config => {
axiosInstance.defaults.baseURL=await getBaseUrl();
return config;
},
error => Promise.reject(error)
);
export async function getBaseUrl() {
var No = await AsyncStorage.getItem('dealerNo')
var value =API_END_POINTS.BASE_URL+ No;
return value;
}
axiosInstance.defaults.headers.post['Content-Type'] = 'application/json';
export default axiosInstance;
iam importing the above axiosInstance to make get or post calls.

Make a function that returns the Axios instance with a dynamic base URL, like this:
custom-axios.js
import axios from 'axios';
const customAxios = (dynamicBaseURL) => {
// axios instance for making requests
const axiosInstance = axios.create({
baseURL: dynamicBaseURL
});
return axiosInstance;
};
export default customAxios;
and then use the instance as follows:
import axios from './custom-axios'
...
const axios1 = axios('/some-url');
const axios2 = axios('/another-url');
axios1.get('/base-is-some-url');
axios2.get('/base-is-another-url');
...

Instaed of axiosInstance.defaults.baseURL, config.baseURL = await getBaseURL(); is enough and should work.
At least it sets baseURL corrrectly in my side.

Related

NextJS: error in getServerSideProps function with axios

On the main page (index.js file) I use the getServerSideProps function
export async function getServerSideProps(context) {
axios.defaults.headers.common['Lang'] = context.locale
try {
const response = await axios.get('/index?limit=8')
return {
props: {
data: response.data
},
};
} catch (error) {
return {
props: {
error: error
},
};
}
}
Everything used to work, but now it's starting to make a mistake
connect EADDRNOTAVAIL ip:443 - Local (ip:0)
Although if you make a request to the same address in useEffect () - everything works
Tried to upgrade next to version 12 - the error remained
Screenshot
try
const response = await axios.get(`https://yourserver.com/index?limit=8`)
and if works replace https://yourserver.com by your .env variable
Also, try to console.log your variable:
const response = await axios.get('/index?limit=8')
console.log(response)
And check if your API route has .get method
In getServerSideProps you have to type the whole url http://localhost:3000/api/my-end-point
So I have two instances of axios in nextjs.
import Axios from 'axios'
// Use in react component
const ClientAxios = Axios.create({
baseURL: '/api'
})
// Use in getServerSideProps
const SystemAxios = Axios.create({
baseURL: 'http://localhost:3000/api'
})

Easy way to append token key to request data for every request with React Query

I have to add a token that is created upon login and put in cookies into my request data to every fetch request I make. I'm currently doing it by using a custom hook that will add it every time so I don't have to add it multiple times. Is there an easier way? Maybe with axios?
Here is my custom hook:
import { useQuery as useBaseQuery } from 'react-query';
import axios from 'axios';
const fetcher = async (url, options) => {
const token = Cookies.get('TOKEN');
const { data } = await axios.get(url, {
data: { ...options, 'TOKEN': token },
});
return data;
};
const useQuery = (queryKey, query, options) => {
return useBaseQuery(queryKey, async () => {
return await fetcher(query, options);
});
};
export default useQuery;
and is used like this:
import useQuery from './useBaseQuery';
const requestData = {
method: 'GET',
path: pathToUrl,
};
export default function useGetActionAlerts() {
return useQuery('actionAlerts', '/bin/user', requestData);
}
You need to use interceptor, from documentation
You can intercept requests or responses before they are handled by then or catch.
https://axios-http.com/docs/interceptors

Multiple Axios Requests Into Vue

I have two different json endpoints I'm using in a Vue JS app. Currently I'm display's posts in a home view. Then using Vue router I'm creating a details view with more specific post info. I would like to for comments to show up from endpoint /comments to appear in the details view if the comment id matches the post id.
posts /posts
comments /comments
import axios from 'axios'
const instance = axios.create({
baseURL: 'https://jsonplaceholder.typicode.com/'
})
const basePost = '/posts'
const baseComments = '/comments'
export default {
fetchPosts () {
return instance
.get(basePost)
.then(response => response.data)
}
}
How would I concatenate both arrays into one and then set that to retrieve posts and comments in a view?
Since axios get returns promise, so u can call both parallel and get the promises to resolve using Promise.all.
Example 1: Using Promise.all
//const axios = require("axios");
const instance = axios.create({
baseURL: "https://jsonplaceholder.typicode.com/",
});
const basePost = "/posts";
const baseComments = "/comments";
const service = {
fetchPosts() {
const promises = [instance.get(basePost), instance.get(baseComments)];
return Promise.all(promises).then(([posts, comments]) => [
posts.data,
comments.data,
]);
},
};
service.fetchPosts().then(console.log);
// export default service;
.as-console-row {
color: blue !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.js"></script>
Note: If you want in series way meaning post first then comment u can use async-await.
Example 2: Using async-await
//const axios = require("axios");
const instance = axios.create({
baseURL: "https://jsonplaceholder.typicode.com/",
});
const basePost = "/posts";
const baseComments = "/comments";
const service = {
async fetchPosts() {
const posts = await instance.get(basePost).then((x) => x.data);
const comments = await instance.get(baseComments).then((x) => x.data);
//console.log(posts, comments);
return [posts, comments];
},
};
// export default service;
service.fetchPosts().then(console.log);
.as-console-row {
color: blue !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.js"></script>

Using Auth0 React Hook on all Axios requests

I have set up Auth0 with React by following their Quickstart tutorial.
Basically my React app is wrapped around their Context Provider and I have access to the useAuth0 hook in any of my components.
This is how I would make a request to my API:
const TestComponent = () => {
const { getTokenSilently } = useAuth0();
const getObjectsFromAPI = async () => {
const token = await getTokenSilently();
const axiosConfig = {
headers: {
Authorization: "Bearer " + token
}
};
const response = await axios.get(
"/api/objects/",
axiosConfig
);
// ... do something with the response
};
return ... removed code for brevity
};
Is there a way to make the requests without having to write the token and axiosConfig on each request?
I know that I can initialize a new axios instance with a config, but I cannot use the useAuth0 hook outside the Context Provider.
but I cannot use the useAuth0 hook outside the Context Provider.
Right, not sure how you can avoid token generation per request but you can save the axios config part by passing the token to a shared axios instance, something like:
http.js
const instance = axios.create({
// your config
});
export const authorized = (token) => {
instance.defaults.headers.common['Authorization'] = `Bearer ${token}`;
return instance;
}
And in your component:
import http from '/path/to/above/http.js';
const TestComponent = () => {
const { getTokenSilently } = useAuth0();
const getObjectsFromAPI = async () => {
const token = await getTokenSilently();
const response = await http
.authorized(token)
.get('/api/objects/');
// ...
};
};

store.subscribe() not working in helper service function on state change

Basically, I get a token in my login api response which is used in network requests as header. I store this token in my redux store. I use axios for all my api calls. I have created an axios instance like following:
axios.js
const axiosInstance = axios.create({
baseURL: 'http://localhost:3003',
// timeout: 10000,
headers: {
Authorization: ~token~,
environment: 'production'
}
});
So that I can call my apis in thunks like :
const resp = await axiosInstance.get(`/log/dashboardchartdatafromdate=${dateData.dateRange.from}&todate=${dateData.dateRange.to}`);
I have tried subscribing to the redux store like the following inside axios.js:
import configureStore from '../store';
configureStore().subscribe(() => {
token = configureStore().getState().loginReducer.token; //access token here
console.log(token);
});
My store looks like this:
store.js
export default function configureStore(initialState) {
const composeEnhancers = window.REDUX_DEVTOOLS_EXTENSION_COMPOSE || compose;
return createStore(reducers, composeEnhancers(applyMiddleware(thunk)));
}
My problem is the code block is not working on state changes. It only works once on the application start.
I am not sure if I can subscribe store inside a helper service function like I have tried. Please correct me if I'm doing it wrong.
Your action creator will just have to look something like this. You can make use of the optional getState() function that is available as an argument inside thunk actions. This is a better alternative than having to subscribe to your store.
axiosInstance.js:
export default const axiosInstance = (token) => {
return axios.create({
baseURL: 'http://localhost:3003',
// timeout: 10000,
headers: {
Authorization: token,
environment: 'production'
}
});
}
Your action file:
import axiosInstance from "./axiosInstance"
const getDashboardData = (dateData) => {
return (dispatch, getState) => {
const token = getState().loginReducer.token
const resp = axiosInstance(token).get(`/log/dashboardchartdatafromdate=${dateData.dateRange.from}&todate=${dateData.dateRange.to}`);
}
}

Resources