meci
meci

Reputation: 209

How to use an API, that is initialized asynchronously, inside a Vuex state?

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!

Upvotes: 2

Views: 1279

Answers (2)

Phil
Phil

Reputation: 164813

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.

Upvotes: 1

Anant Vikram Singh
Anant Vikram Singh

Reputation: 558

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
};

Upvotes: 0

Related Questions