1

I'm facing a weird issue right now. I have a vuex store in my vue project which is seperated in different modules. I want to use Promise.all() to execute two independent async vuex action at once to enjoy the advantage of the first fail behavior.

store/modules/categories:

    async CATEGORIES({ rootState }) {
        const response = await axios.post('link_to_api', {
            // some arguments for the api
            arg: rootState.args
        })

        return response
    }

store/modules/transportation:

    async TRANSPORTATION({ rootState }) {
         const response = await axios.post('link_to_api', {
            // some arguments for the api
            arg: rootState.args
        })

        return response
    }

I know want to call those async functions in Promise.all:

store/modules/categories:

    async PUT_CATEGORIES({ commit, dispatch, rootState }) {
      try {
         const [resCategories, resTransportation] = await Promise.all([
            dispatch('CATEGORIES').catch(err => { console.log('Fehler bei Kabinenabfrage!'); throw {error: err, origin: 'kabine'}; }),
            dispatch('transportation/TRANSPORTATION', {root:true}).catch(err => { console.log('Fehler bei Flugabfrage!'); throw {error: err, origin: 'flug'}; })
        ]) 
         //do something after both promises resolved

      } catch(error) {
            // do something if one promise rejected
            commit('errorlog/ERROR', 4, {root:true})
            dispatch("errorlog/LOG_ERROR", {'origin': '2', 'error_code': '113', 'message': error.toString()}, {root:true})
            router.push({path: '/Error'})
        }  

I get the following error:

error message

This is weird because I used {root:true} and the prefix transport in dispatch to access the action of the transport module in store. This works great for the LOG_ERROR action in the errorlog module I use in the catch block.

If I copy the TRANSPORTATION action in the categories module it works great...

Has anybody faced this issue before and has an advice??

Thanks in advance!

Matthias
  • 3,729
  • 22
  • 37
  • 2
    It's weird to mix `await` with `.catch` but also `try/catch` – VLAZ Feb 10 '20 at 09:18
  • 1
    does `dispatch` return a Promise? or does it return `undefined` as suggested by the error? *`cannot read property 'catch' of undefined`* – Jaromanda X Feb 10 '20 at 09:20
  • 2
    Error is nowhere related to `Promise.all` – AZ_ Feb 10 '20 at 09:22
  • It should return a promise but it seems that it doesn't get the connection to the *TRANSPORT* action in the other modules and therefore it's `undefined` @Jaromanda X – Matthias Feb 10 '20 at 09:23
  • 1
    very odd for something to return a Promise under some conditions and not others – Jaromanda X Feb 10 '20 at 09:25
  • Could you explain wy this is weird @VLAZ? I followed the answer of @mikep in this [post](https://stackoverflow.com/questions/45285129/any-difference-between-await-promise-all-and-multiple-await). – Matthias Feb 10 '20 at 09:25
  • shouldn't `dispatch('transportation/TRANSPORTATION'` be `dispatch('TRANSPORTATION'` as the error says there's no action specified with the provided namespace? – AZ_ Feb 10 '20 at 09:31
  • I tried that and the error message said `[vuex] unknown local action type: TRANSPORTATION, global type: categories/TRANSPORTATION` – Matthias Feb 10 '20 at 09:33
  • It is (as already stated) not a problem of ```Promise.all```. The problem is your dispatch which returns undefined because your action is not found. In your post you say prefix ```transport``` but write ```transportation```. What is the namespace name in your store module definition? Also ```{root:true}``` should be third argument, not the second, pass ```null``` if need be as the second argument and do not prefix if you use ```root``` – grodzi Feb 10 '20 at 10:36
  • Thanks a lot @grodzi!! Passing `null` as second and then `{root:true}` as third argument did the trick. It works now :D You want to write this as answer, so I can accept it? – Matthias Feb 10 '20 at 10:51

1 Answers1

1

In your case, {root:true} is passed as second argument although it should be passed as third.

- dispatch('transportation/TRANSPORTATION', {root:true})
+ dispatch('transportation/TRANSPORTATION', null, {root:true})

According to vuex's doc

To dispatch actions or commit mutations in the global namespace, pass { root: true } as the 3rd argument to dispatch and commit.

They also provide a sample code (which is further simplified here)

modules: {
  foo: {
    namespaced: true,
    actions: {
      // dispatch and commit are also localized for this module
      // they will accept `root` option for the root dispatch/commit
      someAction ({ dispatch, commit, getters, rootGetters }) {
        dispatch('someOtherAction') // -> 'foo/someOtherAction'
        dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction'
grodzi
  • 5,633
  • 1
  • 15
  • 15