2

I'm introducing myself to Vue + Vuex and I'm having a hard time figuring out where to initialize an API that has an async initialization method.

I obviously can't await outside an async function like this:

import { RequestSystemProxy } from "../../assets/scripts/RequestSystemProxy"

const system = new RequestSystemProxy();

const handle = await system.Initialize();

const state = { ... };

const getters = { ... };

const actions = { ... methods that use 'handle' ... };

const mutations = { ... };

export default {
    state,
    getters,
    actions,
    mutations
}

and Vue doesn't like it when I export a promise like this:

import { RequestSystemProxy } from "../../assets/scripts/RequestSystemProxy"

export default (async function () {

    const system = new RequestSystemProxy();

    const handle = await system.Initialize();

    const state = { ... };

    const getters = { ... };

    const actions = { ... methods that use 'handle' ... };

    const mutations = { ... };

    return {
        state,
        getters,
        actions,
        mutations
    }

})();

My intention is to use handle inside actions to make various async requests but that obviously can't happen until the handle has resolved.

I'm at a bit of a loss here, I'm not sure where the best place to put this is. I suppose I could initialize handle globally, before I initialize the Vue app, but that puts the initialization, structurally, pretty far away from where it's used. Is there a typical approach for doing something like this?

Any help would be really appreciated!

meci
  • 199
  • 6
  • Looks like you are trying to execute the function while exporting it with the ending (). Try just doing export default async () => {} – Devon Norris Mar 20 '20 at 03:10
  • 1
    @DevonNorris I think OP meant to execute the function – Phil Mar 20 '20 at 03:11
  • Seems like an anitpattern to me, but idk – Devon Norris Mar 20 '20 at 03:16
  • 1
    I did mean to execute the function. I don't want to return the function itself, I wanted invoke the function immediately and export its result `{ state, getters, actions, mutations }` – meci Mar 20 '20 at 03:16
  • I think you should just import this function/file into the file you want to use it in. Inside of another function, just call `const { state, getters, actions, mutations } = await fileImport()` – Devon Norris Mar 20 '20 at 03:25

2 Answers2

1

Actions can be asynchronous so just store a reference to your system.Initialize() promise and prefix each action by waiting for that promise to resolve.

import { RequestSystemProxy } from '../../assets/scripts/RequestSystemProxy'

const system = new RequestSystemProxy()
const initPromise = system.Initialize()

const state = { ... }

const getters = { ... }

const mutations = { ... }

const actions = {
  async exampleAction (context) {
    const handle = await initPromise
    // now use handle 
  }
}

export default {
  state,
  getters,
  actions,
  mutations
}

Another option is to have your module (let's call it store.js) export a promise

import { RequestSystemProxy } from '../../assets/scripts/RequestSystemProxy'

const system = new RequestSystemProxy()

export default system.Initialize().then(handle => {
  // now initialize your store...

  return {
    state,
    getters,
    // etc

  }
})

and then consume the promise in your main.js (or whatever)

import storePromise from 'path/to/store.js'

storePromise.then(store => {
  new Vue({
    store,
    // etc
  }).$mount('#app')
})

Note: This would require consideration of how you handle the UI before the root Vue instance is initialized and mounted.

Phil
  • 157,677
  • 23
  • 242
  • 245
0

yuu need to create actions (which is nothing but method only) inside your store

const actions = {
  async actionName({ state }) {
    // write your code in here
  },
}

also you can write this

export default {
  namespaced: true,
  state,
  getters,
  actions,
  mutations
};
Anant Vikram Singh
  • 538
  • 1
  • 4
  • 14