How to make axios's API requests reusable with vuejs? - vue.js

How can I make axios's API requests reusable through my app,
so I can avoid writing writing the same code over and over again..
//load the axios HTTP library
window.axios = require('axios');
window.Vue = require('vue');
const app = new Vue({
el: '#app',
mounted(){
console.log('hello!');
}
});
I was thinking of trying something like this ( gist ) but I don't know how can I attach the functions to Vue instance and call these functions from vue-components directly ..

You can inject axios as Vue property :
Vue.prototype.$http = require('axios');
Then you can use it like that : this.$http.get(...)
Or you can checkout this repository

Related

How do I access this.$vuetify using Composition API in Vue 2?

I'm trying to read and change the value of this.$vuetify.dark using composition API in Vue 2 + Vuetify 2. Now that this.myGlobalOption is no longer accessible in composition API, how do I do this? I'm gonna need to do this both from within the template and from outside.
You can make a helper function(composable?) like this:
import { getCurrentInstance } from 'vue';
export const useVuetify = () => {
const vm = getCurrentInstance();
return vm.proxy?.$vuetify || undefined;
};
Then in your component you can get access to vuetify instance via:
const vuetify = useVuetify();

Forward basiauth to axios

I have a site which makes an Axios request. Both the backend and vuejs frontend are on the same domain, and have the same basic auth covering them.
The issue is that whilst the pages load, as soon as an Axios request is made, it asks me again for the basic auth, which doesn't even work if I fill in the details.
Now I imagine I need to pass through the basic auth details somehow, but none of the things I have tried work (and example being below).
If anyone has any tips on passing through the auth token from the parent page to the axios request, that would be great.
const requestOne = axios.get(requestUrl)
const requestTwo = axios.get(requestUrl)
axios
.all([requestOne, requestTwo])
.then(
axios.spread((...responses) => {
<some code here>
})
)
I just answered a similar question with the 3 ways to pass around data in Vue.
You might find it helpful: How to pass v-for index to other components
However, in my opinion, the best approach would be to create a Vue plugin with your Axios client and an init method.
Consider this following (untested) example:
axiosClient.js
import Vue from 'vue';
let instance;
export const getInstance = () => instance;
export const useAxios = () => {
if (instance) return instance;
instance = new Vue({
data() {
return {
client: null,
}
}
});
methods: {
init(authToken) {
this.client = axios.create({
headers: {'Authorization': authToken }
});
}
}
}
export const axiosPlugin = {
install(Vue) {
Vue.prototype.$axios = useAxios();
},
};
Vue.use(axiosPlugin);
Once installed, you can access this in your components using $axios.init(...) and $axios.client.
You can even write API methods directly onto the plugin as well and interact with Vuex through the plugin!
You may need to tweak the plugin a little (and keep in mind this is Vue2 syntax) as I wrote this directly into StackOverflow.
You can also pass any other default values or configuration options through to the axios client by providing options to the plugin and accessing them within init.
You can learn more about plugins here: https://v2.vuejs.org/v2/guide/plugins.html

how to use global function with plugin to show notification in vue.js?

I'm trying to make a global function with help of plugin which it worked fine but i couldn't show my notification. I was doing my homework and i tried to not write everywhere those show notification methods, so I've searched and i found this solution and i managed to add plugin now i wan to use it in my component. here's the code :
AppNotifications.js
export default {
failedNotification(title, data) {
return this.$vs.notify({
title:title,
text:data,
color:'danger',
position:'bottom-center',
});
}
};
App.js
import Vue from 'vue'
import notifications from './Helpers/AppNotifications'
const plugin = {
install () {
Vue.notifications = notifications
Vue.prototype.$notifications = notifications
}
}
Vue.use(plugin)
const app = new Vue({
vuetify,
el: '#app',
render: h => h(App),
router
});
And in componenets when i use a button with #click="SomeMethod" i use plugin like this :
this.$notifications.failedNotification('Test','Just Failed, yay')
So function work but i get this error
Error in v-on handler: "TypeError: Cannot read property 'notify' of undefined"
Since I'm in learning process i wasn't familiar with this issue and I've tried to import vue and notification component itself but didn't worked.
Edit 01 : Notification is belong to Vuesax library and it's already imported in App.js and it's working fine when i use it in vue components but it's not working when i use it in AppNotification.js
So i found the solution for my problem and it fixed with sending this as parameter to function.
Vue Component :
//this was before the problem
this.$notifications.failedNotification('Test','Just Failed, yay')
//then i added this as parameter
this.$notifications.failedNotification(this,'Test','Just Failed, yay')
And in AppNotification.js
//Before changing
failedNotification(title, data) {
return this.$vs.notify({
title:title,
text:data,
color:'danger',
position:'bottom-center',
});
}
//Then i added self and replaced self with `this`
failedNotification(self,title, data) {
return self.$vs.notify({
title:title,
text:data,
color:'danger',
position:'bottom-center',
});
}
And it's worked.
The error you're getting suggests that the notification library you're using isn't being loaded and if you posted the entire code of your App.js file then it looks like you're missing some code.
The file probably needs to look something like this:
import Vue from 'vue'
import Vuesax from 'vuesax'
import notifications from './Helpers/AppNotifications'
import 'vuesax/dist/vuesax.css' //Vuesax styles
const plugin = {
install () {
Vue.notifications = notifications
Vue.prototype.$notifications = notifications
}
}
Vue.use(Vuesax)
Vue.use(plugin)
const app = new Vue({
vuetify, // <-- not sure where vuetify is coming from?
el: '#app',
render: h => h(App),
router
});

Vue.JS Vuex store and accessing my api through dependency injection

I'm having difficulties accessing my api within my store modules. I've created an instance of my api, passed it within my vue creation just like the store. However when trying to implement logic in my module, the this.$api does not work like it works in my components. Is there any way to access my already created instance of api?
const api = new Api();
/* eslint-disable no-new */
new Vue({
components: {App},
router,
api, // <--- I want this.
store, // <--- To be accesable in the modules of this
template: '<App/>'
}).$mount('#app');
So can I access the api instance without creating a new instance in my module or store?
I think you should be able to inject api directly to store, like this:
const store = new Vuex.Store();
const $axios = axios.create();
store.$axios = $axios;
new Vue({
components: {App},
router,
store,
template: '<App/>'
}).$mount('#app');
Anyways, for Axios, it worked fine: https://forum.vuejs.org/t/accessing-axios-in-vuex-module/29414/3

Populate router with external json

I would like to add routes from an external json file, which can change at runtime, to my Nuxt application. A similar topic can be found here.
I've overridden the default Nuxt router with my own implementation. If I import the routes async using axios + router.addRoutes(), I seem to loose the server side rendering. It seems like createRouter will have async support, but it's not in an official release of Nuxt yet.
How do I import a js/json file synchronously to my router.js below, so that I can populate the routes? I want to be able to configure the routes at runtime, so I don't want it to be a part of the bundle.
modules/router.js:
const path = require('path')
module.exports = function () {
this.nuxt.options.build.createRoutes = () => {}
this.addTemplate({
fileName: 'router.js',
src: path.resolve(`${this.options.srcDir}`, 'router.js')
})
}
nuxt.config.js:
modules: ['~/modules/router']
router.js:
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export function createRouter () {
const router = new Router({
mode: 'history',
routes: [/* ... */]
})
return router
}
You could try with sync-request.
It is a NPM package aimed to perform synchronous web requests. It is available here.
Please note that, as stated in the documentation of the package itself, it is not suitable for production environment, probably because of application hanging in case of missing data.
So await would be an answer but I guess you already tried that? So, something like this.
const routeFile = await fetch('pathToTheJsonFile');
const routes = await routeFile.json();
In case you can't make the method async, as a workaround maybe use jQuery. I don't like this but if there's no other option, for now, use async: false in jQuery get.
jQuery.ajax({
url: 'pathToYourJsonRoutes',
success: function (result) {
},
async: false
});