I'm building an application on Vue 3
where I've build an api
class for my api calls:
import axios from 'axios'
export default class {
/**
* Send GET Request
* @param {string} url
* @return {Promise}
*/
get(url) {
return new Promise((resolve, reject) => {
axios.get(url, {}).then(response => {
if (response.status === 200) {
return resolve(response);
}
}).catch((error) => {
return reject(error);
})
});
}
/**
* Send POST Request
* @param {string} url
* @param {object} payload Data object to send
* @return {Promise}
*/
post(url, payload) {
return new Promise((resolve, reject) => {
axios.post(url, payload, {}).then(response => {
if (response.status === 200) {
return resolve(response);
}
}).catch((error) => {
return reject(error);
})
});
}
/**
* Send FIND Request
* @param {string} url
* @return {Promise}
*/
find(url) {
return new Promise((resolve, reject) => {
axios.get(url, {}).then(response => {
if (response.status === 200) {
return resolve(response);
}
}).catch((error) => {
return reject(error);
})
});
}
}
I want to utilize this class functions inside my Vue components, for this I imported the _api.js
file and inserted .provide('$api', apis)
into createApp
function in app.js
file:
import { createApp, h } from 'vue';
import { createInertiaApp } from '@inertiajs/inertia-vue3';
import api from './Models/_api'
const apis = new api();
createInertiaApp({
resolve: (name) => require(`./Pages/${name}.vue`),
setup({ el, app, props, plugin }) {
return createApp({ render: () => h(app, props) })
.use(plugin)
.mixin({ methods: { route } })
.provide('$api', apis)
.mount(el);
},
});
And in my component I'm using as:
<template>
//HTML Files
</template>
export default {
data(){
return{
tableData:[],
}
},
methods:{
fetchData(){
this.$api.post('/api/user-data', {}).then(response=>{
if(response.status === 200)
{
this.tableData = response.data.data
}
});
}
},
created(){
this.fetchData();
},
}
</script>
while using this.$api
I'm getting error:
TypeError: Cannot read properties of undefined (reading 'post')
Screenshot:
when I tried console.log(this.$api)
it returned undefined
Below solution working in Vue 2
In Vue 2
it was working perfectly fine:
I only have to initiate the class in app.js
and add it to prototype
and it works good.
Vue 2 Code app.js
:
import { App, plugin } from '@inertiajs/inertia-vue'
import Vue from 'vue'
import api from './Models/_api'
const apis = new api();
Vue.prototype.$api = apis;
const el = document.getElementById('app')
new Vue({
store: store,
render: h => h(App, {
props: {
initialPage: JSON.parse(el.dataset.page),
resolveComponent: name => import(`NitsPages/${name}`).then(module => module.default),
},
}),
}).$mount(el)
CodePudding user response:
This is be related to Vue3 reserving _
and $
prefixes.
Properties that start with _ or $ will not be proxied on the component instance because they may conflict with Vue's internal properties and API methods. You will have to access them as this.$data._property.
So try the following:
this.$data.$api.post(...)
Personally, I think using those two common conventions and reserving them for internal use was not ideal. But it is what it is. You can read more about it here. https://github.com/vuejs/vue/issues/5879
CodePudding user response:
You can add your API Class as a global Property to your Vue 3 Instance.
This is stated in the Vue 3 Application Documentation.
e.g.:
main.js
import { createApp, h } from 'vue';
import { createInertiaApp } from '@inertiajs/inertia-vue3';
import api from './Models/_api'
const apis = new api();
createInertiaApp({
resolve: (name) => require(`./Pages/${name}.vue`),
setup({ el, app, props, plugin }) {
const app = createApp({ render: () => h(app, props) });
app.config.globalPoperties.api = apis;
return
.use(plugin)
.mixin({ methods: { route } })
.provide('$api', apis)
.mount(el);
},
});
Which will then be callable anywhere inside your Vue Components with this.API