axios instance not working as expected in React.js - javascript

I have a component called Login.js There I import Axios libray normal way and it works like this.
import axios from 'axios';
const data = await axios.post('/user/login/', {
email: e.email,
password: e.password,
});
Getting 404 is fine because I didn't set any base URL for the Axios. Please note all the requests, response headers here.
Then I try to created Axios instance inside a lib folder and import it like this
/src/lib/axios.js
import axios from "axios";
const baseUrl = process.env.REACT_APP_BE_URL;
const axiosInstance = axios.create({
baseURL: baseUrl,
});
export default axiosInstance;
I import this instance instead of normal Axios import.
import axios from 'libs/axios';
Now I see the request like this a lot of properties missing in the request and this isn't working
How do I fix this?
Any help thanks in advance.

Related

After I have installed axios How to import it on y project vuejs

hope you are well!
I am working in a project CRUD web application that handles user management. Create user, edit user, delete user.
First I set up my project install VueJS after that installed vue-bootstrap make import in file main.js.
For mocking the Backend I have used :
NPM install -g json-server
After that, create a new file called db.json that handles users in the root of a project.
I run command json-server --watch db.json to make record available.
http://localhost:3000/users
I have installed axis for us to be able to send and receive data from our backand.
So I have run command npm install axios.
But after it how I have import axios in file main.js, but I am not confident if is the right way?? Thanks
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import { BootstrapVue, IconsPlugin } from "bootstrap-vue";
import axios from 'axios'
//Import Bootstrap an BootstrapVue CSS files (order is important)
import "bootstrap/dist/css/bootstrap.css";
import "bootstrap-vue/dist/bootstrap-vue.css";
// Make BootstrapVue available throughout your project
Vue.use(BootstrapVue);
Vue.use(IconsPlugin);
Vue.config.productionTip = false
Vue.use({
install (Vue) {
Vue.prototype.$api = axios.create({
baseURL: 'http://localhost:8000/users/'
})
}
})
new Vue({
router,
render: h => h(App)
}).$mount('#app')
<script>
import axios from 'axios';
export default {
data() {
return {
posts: [],
errors: []
}
},
// Fetches posts when the component is created.
created() {
axios.get(`http://jsonplaceholder.typicode.com/posts`)
.then(response => {
// JSON responses are automatically parsed.
this.posts = response.data
})
.catch(e => {
this.errors.push(e)
})
}
}
</script>
Do the same as shown in the script example, it will work
Fetching data from external sources is considered as a "side-effect". Thus, according to me, you should perform such side effects inside a "mounted" life cycle.
Further, to make things more better, you can create an abstraction layer for fetching data from external APIs inside "mounted" life cycle.
To make things simple on your end, you can also consider Vue-Query.
the easiest way is to create a folder known as axios in your src then add index.js in it then put this code:
// axios/index.js
import axios from "axios";
export default axios.create({
baseURL: "http://127.0.0.1:8000/api/", //your base url here
});
then import this file as axios in your app main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import { BootstrapVue, IconsPlugin } from "bootstrap-vue";
import axios from "#/axios"; //import your custom axios

axios using wrong base url

I have a react project where I'm making requests to a third-party api. I created an axios file where I set a baseUrl for requests, and I export a function which will make a request to a particular endpoint.
However, when I import and execute the function in my App.js, the request is made with localhost:3000 as the base url. Can't figure out why
I made a sandbox to demonstrate
here is the code for my axios.js file
import axios from 'axios'
const instance = axios.create({
baseUrl: `https://api.-----.com/svc/topstories/v2/`
})
export const api_key = '------------------------'
export const getTopStories = async () => {
const {data: {results}} = await instance.get(`/home.json?api-key=${api_key}`)
return results
}
export default instance
You should use baseURL instead of baseUrl

ReactJS - Importing store breaks Jest

I had a file with one function that creates an axiosInstance, it used to look like this:
import Axios from 'axios';
import getToken from '#/api/auth-token';
const [apiUrl] = [window.variables.apiUrl];
export const createApiInstance = () => {
return Axios.create({
baseURL: `${apiUrl}`,
headers: {
Authorization: `Bearer ${getToken()}`,
},
});
};
Something we wanted to implement was notifying the user when their JWT token expires (so they won't unwittingly continue using the app while all of their requests are returning 401s). My solution turned this file into this:
import Axios from 'axios';
import getToken from '#/api/auth-token';
import store from '#/main.jsx';
import { userActionCreators } from '#/store/action-creators';
const [apiUrl] = [window.variables.apiUrl];
export const createApiInstance = (urlExtension = '') => {
const axiosInstance = Axios.create({
baseURL: `${apiUrl + urlExtension}`,
headers: {
Authorization: `Bearer ${getToken()}`,
},
});
axiosInstance.interceptors.response.use(response => {
if (response.status === 401)
store.dispatch(userActionCreators.setUserTokenExpired());
return response;
});
return axiosInstance;
};
This worked very well, as now all of the responses from the API are being checked for a 401 Unauthorized status and dispatching an action so the app can respond to it.
Jest doesn't like the import store, so 95% of the tests in the app fail when the store is imported here. I'm certain it is the importing of the store because every test passes when it is commented it.
I've had absolutely no luck getting anything to work.
I've tried updating setting jest and babel-jest to the same versions, setting react, react-dom, and react-test-renderer to the same versions. I've looked into configuring moduleNameMapper to mock the store in the jest config in package.json but I'm not sure how to make that work. I'm starting to consider taking a completely different approach to this problem such as applying middleware to check for 401 responses instead, but I'm worried I'll end up running into the same issue after a bunch of work.
The problem with mocking the store in the test files themselves is that there's hundreds of test files in this large application, so literally anything besides adding mocking to each individual file is the solution I'm looking for.
If anyone else is having this problem, this occurred because I was exporting the store from the same file as my ReactDOM.render. Apparently you can export from this file but as soon as you try to import what is exported somewhere else it will catch it and break tests. The solution is to create and export the store from a different file.
Make sure you have a .babelrc file, as jest doesn't understand the context of babel and JSX files otherwise. Related Stack Qusetion
If that doesn't quite do the trick can you update with the main.jsx code and let me know then i'll update

axios is not defined in vue js cli

I installed axios using the npm install axios command this is my package.json dependencies
"dependencies": {
"axios": "^0.18.0",
"bootstrap-vue": "^2.0.0-rc.11",
"vue": "^2.5.2",
"vue-router": "^3.0.1"
},
I registered the axios in my main.js file.
import Vue from 'vue'
import VueRouter from 'vue-router'
import BootstrapVue from 'bootstrap-vue'
import axios from 'axios'
import App from './App'
import routerList from './routes'
Vue.use(axios)
Vue.use(BootstrapVue)
Vue.use(VueRouter)
When I tried to use axios in one of my components I get this error:
Uncaught ReferenceError: axios is not defined
How to fix this?
Vue.use means adding plugins. However, axios is not a plugin for Vue, so you can not add it globally via use.
My recommendation is importing axios only when you need it. But if you really need to access it globally, you may like to add it to prototype.
Vue.prototype.$axios = axios
Then you can access axios in vue using this.$axios
Solution 1 (Not recommended):
In main.js, add this line instead of import axios from 'axios'
window.axios = require('axios');
And remove
Vue.use(axios)
Solution 2 (Recommended Approach):
Using window is generally considered a bad practice, so you better use axios the following way:
Create a folder named plugins inside of your src directory.
Then, create axios.js file inside that directory. We will put all our axios logic here and use axios as a Vue plugin.
Add the following:
import ax from 'axios'
// insert all your axios logic here
export const axios = ax
export default {
install (Vue, options) {
Vue.prototype.$axios = ax
}
}
In src/main.js, add the following:
import Vue from 'vue' // You can skip this line
import VueAxios from './plugins/axios'
Vue.use(VueAxios)
Now, you can use axios as this.$axios in your components. So something like this.$axios.get().
Therefore, you can import axios with the following line:
import { axios } from '#/plugins/axios'
Now, you can use axios directly in your store.
Or you can also use it as Vuex plugin:
import { axios } from '#/plugins/axios'
const axiosPlugin = store => {
store.$axios = axios
}
new Vuex.Store({
...,
plugins: [axiosPlugin]
})
Now, you can use it as this.$axios in Vuex.
Use following command to install axios
npm install axios --save
After executing above command import like mentioned below:
import axios from 'axios'
Also install vue-axios and import in main.js
import VueAxios from 'vue-axios'
Then in main.js:
Vue.use(VueAxios, axios)
Now if I am not mistaken in your methods you can use for example:
let uri = 'http://localhost:4000/tickets/add';
this.axios.post(uri, this.ticket).then((response) => {
console.log(response);
});
import Vue from 'vue'
import axios from 'axios'
Vue.prototype.$http = axios;
then inside your component you can start using axios like this:
{
methods: {
someMethod() {
this.$http.get('/users').then(() => {
// do something
})
}
}
}
Include this line:
import {AxiosInstance as axios} from "axios";
To use in Vue Components, install both Vue Axios and Axios packages
npm install --save axios vue-axios
In your main.js file, add the following:
import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
With the above solution, I never had an issue using axios in my Vue components with this keyword till now.
Custom Javascript File
However, I had faced issues using Axios in a custom JS file with axios not defined error.
Following worked for me in a custom JS file:
const axios = require("axios");
Usage example:
export default {
fetchProducts() {
return axios.get(`${ROOT_URL}/products`);
},
};
Try this codes:
import axios from 'axios'
Vue.use(axios)

Creating an instance of axios in Vue not working

I am using axios for AJAX in Vue. In the article written by You, he mentioned that we can set Vue.prototype.$http = axios and I can use this.$http in Vue instance. It works fine.
However, if I want to create an axios instance to $http, like
Vue.prototype.$http = axios.create({
baseURL: 'https://app.herokuapp.com/'
})
It does not work when I use this.$http.get('/relativeURL'). It seems that it cannot access the config I set. That is, it will not send request to https://app.herokuapp.com/relativeURL
In another way, if I set axios instance in any other object, such as Vue.prototype.$axios = axios.create({config}). It works successfully.
Could someone explain why this happen ??
While defining it at Vue instance level might have its own merit, I don't like to pollute the global namespace. What my approach is, I have a gateway folder, where I have different files for axios instance, such as:
backend-api.js
import axios from 'axios'
export default axios.create({
baseURL: 'http://YourAPiIp:9090/api/v1',
timeout: 100000,
headers: {
'Content-Type': 'application/json'
}
})
Now you can import it the place you want and use it:
import backendApi from '../../gateways/backend-api'
You set
Vue.prototype.$https = axios.create({
baseURL: 'https://app.herokuapp.com/'
})
And use
this.$http...
Typo in property name (https vs http).
Leave it as $http. Or simply don't even declare $http if it misleads you - use just this.axios.get...

Categories

Resources