LuMa
LuMa

Reputation: 1763

Where to update Vuex state with API data

This question is more of a code organization question. I'm new into the whole frontend stuff. I started a simple app powered by VueJS + Vuex + VuerRouter + Vuetify + TypeScript. This is the view of the src folder:

├── App.vue
├── assets
│   └── ...
├── components
│   └── ...
├── plugins
│   └── ...
├── router
│   └── ...
├── services
│   └── StuffAPI.ts
├── store
│   ├── index.ts
│   └── modules
│       └── stuff.ts
└── views
    └── Stuff.vue

I prefetch most of the data needed in App.vue on mounted():

export default class extends Vue {
  listStuffs() {
    StuffAPI.list()
      .then((stuffs: Stuff[]) => {
        this.$store.dispatch("stuff/changeStuffs", stuffs);
      })
      .catch(e => {
        // ...
      });
  }

  mounted() {
    this.listStuffs();
  }
}
</script>

However, there are situations where components alter the data on the server side (e.g. by creating a resource). Now I need to fetch the data from the server again. However, I don't want to copy the listStuffs method throughout the codebase. How do I solve that? I can't call parent methods from a child component. Should I use custom events? Or is it perfectly fine to have a Vuex action which fetches the data?

Upvotes: 1

Views: 808

Answers (1)

Imtiyaz Shaikh
Imtiyaz Shaikh

Reputation: 625

Firstly, you can use 'Mixins' in VueJS. Mixins is a feature that allows you use same function throughout the application components.

Secondly, you can use Vuex.

  1. Create a store. (Ex: CustomAPI.js)
  2. Write Getters, Mutations and Actions in the file
  3. Call the actions in components (ex: this.$store.dispatch('StuffAPI').then()
  4. Keep Mutating the StuffAPI result in the store
  5. Fetch the mutated data using Getters

For reference, check below code:

import * as types from '../types'
// Import axios or any http client

export const state = {
  isLoggedIn: false
}

export const getters = {
  isLoggedIn: state => state.isLoggedIn
}

export const mutations = {
  [types.MUTATE_LOGIN_FLAG]: (state, isLoggedIn) => {
    state.isLoggedIn = isLoggedIn
  }
}

export const actions = {

  AUTH_LOGIN: ({ commit }, payload) => {
    return new Promise((resolve, reject) => {
      // MY HTTP LOGIN REQUEST CODE HERE

    //   On result..
    commit(types.MUTATE_LOGIN_FLAG, true)
    })
  },

  AUTH_LOGOUT: ({ commit }, payload) => {
    return new Promise((resolve, reject) => {
    //  MY HTTP LOGOUT REQUEST CODE HERE

    // ... On result, 
    commit(types.MUTATE_LOGIN_FLAG, false)
    })
  }
}

Now, whenever I need login status in some component, I'll use:

this.$store.getters.isLoggedIn

That returns True or False.

Whenever I need to Login or Logout, I'll use:

this.$store.dispatch('AUTH_LOGIN')

I can call these actions anywhere in my application.

Note: This is just a sample implementation. You dont really write login logout in store :D

Upvotes: 1

Related Questions