Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue - Do API calls belong in Vuex?

Tags:

vue.js

axios

vuex

I am struggling with finding answer for where to ideally put API calls in vue modules. I am not building an SPA. For example my auth block has several components for login, password reset, account verifiction etc. Each block uses axios for API calls. Axios already provides promises, which are async.

The question is about the best pracitces. Do API calls belong in a Vuex actions? Are there any pros/cons of such approach?

Is there any drawback of keeping axios calls within the components they belong to?

like image 749
Peter Matisko Avatar asked Jan 29 '18 04:01

Peter Matisko


People also ask

Is Vuex necessary in vue3?

Both of these could do the work of Vuex, but they aren't enough to replace Vuex completely. Let's take a look at why Vuex is is still necessary, even in Vue 3. First, Vuex offers advanced debugging capabilities that Vue 3 features does not.

What is the difference between Vue and Vuex?

Vue is a progressive Javascript framework and Vuex is the state management tool. We can use redux or flux inside Vue, But Vuex is native to the Vue.

What is difference between dispatch and commit in Vuex?

Dispatch triggers an action whereas commit triggers a mutation. $dispatch is always used from your methods in routes/components. It sends a message to Vuex store to perform some action. The action can be performed any time after the current tick so that it will not affect the frontend performance.


1 Answers

I do API calls in services, not Vuex or components. Basically, mixing the API calls in with the store code is a bit too multi-responsibility, and components should be about providing for the view not fetching data.

As an example of a simple service (using Vue.http but same for an Axios call),

FileService .js

import Vue from 'vue'

export default {
  getFileList () {
    return Vue.http.get('filelist.txt')
      .then(response => {
        // massage the response here
        return filelist;
      })
      .catch(err => console.error('getFileList() failed', err) )
  },
}

I use it in another service as below (the number of layers is up to you).
Note, the outer service is checking the store to see if the fetch already happened.

DataService.js

import FileService from './file.service'

checkFiles (page) {
  const files = store.state.pages.files[page]
  if (!files || !files.length) {
    return store.dispatch('waitForFetch', {
      resource: 'files/' + page,
      fetch: () => FileService.getFileList(),
    })
  } else {
    return Promise.resolve()  // eslint-disable-line no-undef
  }
},

waitForFetch is an action that invokes the fetch function passed in to it (as provided by FileService). It basically provides wrapper services to the fetch, like timeout and dispatching success and failure actions depending on the outcome.

The component never knows about the API result (although it may initiate it), it just waits on data to appear in the store.


As for drawback of just calling the API in the component, it depends on testability, app complexity. and team size.

  • Testability - can mock out a service in unit tests.
  • App complexity - can handle timeout / success / failure orthogonally to the API call.
  • Team size - bigger teams, dividing up the task into smaller bites.
like image 61
Richard Matsen Avatar answered Sep 23 '22 05:09

Richard Matsen