1
votes

Almost all of my components require some kind of interaction with my apiservice.js class, which imports Axios and makes appropriate http requests depending on the method called. I know this isn't normally recommended, but, in every one of my components, I have the following:

import {APIService} from '../store/APIService.js';
const apiService = new APIService();

My APIService.js looks roughly like this (trimmed down for simplicity):

import axios from 'axios';
const API_URL = 'http://myserver:82/services/locationmanagement';

export class APIService{

constructor(){
}

getLocations() {
    const url = `${API_URL}/api/locations/`;
    return axios.get(url).then(response => response.data);
}

saveLocation(location) {
    let url = `${API_URL}/api/locations/`;
    let id = location.id;
    let httpMethod = 'post';

    if(id > 0 ) {
        httpMethod = 'put';
        url = `${API_URL}/api/locations/${id}`;
    }

    let options = {
        method: httpMethod,
        url: url,
        headers: { 'Content-Type': 'application/json' },
        data: location
    }

    return axios(options);
   }

}   

I would prefer if this were somehow made available to the global Vue instance and my components could access it somehow.

I believe this needs to be implemented in some form within my main.js file, possibly via Vue.use, but I'm still unsure of how to implement this even after reviewing the docs.

Any input would be greatly appreciated. Thanks!

1
Use Vuex, and make these store actions instead of using a class. Also, you are instantiating your class multiple times needlessly. You could instantiate it once in the external file and export the instance instead of the class itself. - Dan
<-- mind blown! .... i've been using Vuex actions ubiqutiously because "that's what I read", but the implementation was never different than a mutator. I knew i could put asynchronous code in the Actions, but wasn't sure why I would do that...Now I know. - jason
You can think of a global store as a good place for any functionality-- including both data and methods (i.e. state and actions)-- that isn't strictly connected to a component. General app data and loading processes can be a good example of that. - Dan
Yeah, I'm working on moving the saveLocation functionality into an action and storing the result be it success or failure in a "serviceResult" value in the store. I have a DIV in App.vue that gets displayed so long as "serviceResult" has a value. I'm hoping I can use this as a sort of universal "Errors" & "Messages" section in my application without making each component manage that themselves. Furthermore, this would open a means for me to add some kind of logging in the Store which remove more ubiquitous functionality from the components. It's not working quite yet, but I think it will. - jason

1 Answers

1
votes

Create a Vuejs Plugin import it into main.js, and call it there with Vue.use(myservice)

EDIT:

Per comment, one way is to add the plugin to the Vue prototype. For example, an axios wrapper could be defined as

import axios from 'axios'

export default {

  install:function(Vue,options) {

    Vue.prototype.$dataservice = axios.create({...})
    ...

then it can be called from a component like other global vue functions, e.g., $refs, $set, $emit:

 ...
 this.$dataservice.get(...)
 // or
 this.$dataservice.post(...)
 ...

With a data service api, if using Vuex, it may be useful to use this primarily in "actions".