title: Vuex: Wait for websocket response before dispatching action
body: <p>So this is the scenario / premises:</p>
  <ul>
  <li>In order to populate a chat queue in real time I need to open a connection to a websocket, send a message and then set the data to a websocket store. This store will basically manage all the websocket state.</li>
  <li>Before populating the chat queue there's two parameters I need: a shiftId coming from one http API request and a connectionId coming from the websocket. Using those two parameters I finally can subscribe to a third http API and start receiving messages to populate the chat queue.</li>
  </ul>
  <p>The problem is that due to the async behaviour of the websocket (or that's what I think, please feel to correct me if I'm wrong) I always get an empty &quot;connectionId&quot; when trying to make the put to that &quot;subscription&quot; API. I have tried with async/await and promises but nothing seems to work. I'm pretty new to async/await and websockets with Vuex so pretty sure I'm doing something wrong.</p>
  <p>This is the user vuex module where I do all the login/token operations and dispatch a &quot;updateEventsSubscription&quot; action from the shift vuex module. In order for the &quot;updateEventsSubscription&quot; action to work I need to get the response from the &quot;processWebsocket&quot; action (to get the connectionId parameter) and from the &quot;startShift&quot; action (to get the shiftId parameter) coming from the shifts vuex module:</p>
  <pre><code>import UserService from '@/services/UserService.js'
  import TokenService from '@/services/TokenService.js'
  import router from '@/router'
  export const namespaced = true
  export const state = {
      accessToken: '',
      errorMessage: '',
      errorState: false,
      userEmail: localStorage.getItem('userEmail'),
      userPassword: localStorage.getItem('userPassword'),
  }
  export const mutations = {
      SET_TOKEN(state, accessToken) {
          state.accessToken = accessToken
          TokenService.saveToken(accessToken)
      },
      SET_USER(state, authUserJson) {
          state.userEmail = authUserJson.email
          state.userPassword = authUserJson.password
          localStorage.setItem('userPassword', authUserJson.password)
          localStorage.setItem('userEmail', authUserJson.email)
      },
      SET_ERROR(state, error) {
          state.errorState = true
          state.errorMessage = error.data.error_description
      },
      CLOSE_NOTIFICATION(state, newErrorState) {
          state.errorState = newErrorState
      },
  }
  export const actions = {
      signIn({ commit, dispatch, rootState }, authUserJson) {
          return UserService.authUser(authUserJson)
              .then((result) =&gt; {
                  commit('SET_USER', authUserJson)
                  commit('SET_TOKEN', result.data.access_token)
                  dispatch('token/decodeToken', result.data.access_token, {
                      root: true,
                  })
                  dispatch(
                      'shifts/updateEventsSubscription',
                      rootState.token.agentId,
                      {
                          root: true,
                      }
                  )
                  router.push('/support')
              })
              .catch((error) =&gt; {
                  console.log(error)
                  if (error.response.status === 400) {
                      commit('SET_TOKEN', null)
                      commit('SET_USER', {})
                      commit('SET_ERROR', error.response)
                  } else {
                      console.log(error.response)
                  }
              })
      },
      signOut({ commit }) {
          commit('SET_TOKEN', null)
          commit('SET_USER', {})
          localStorage.removeItem('userPassword')
          localStorage.removeItem('userEmail')
          TokenService.removeToken()
          router.push('/')
      },
      closeNotification({ commit }, newErrorState) {
          commit('CLOSE_NOTIFICATION', newErrorState)
      },
  }
  export const getters = {
      getToken: (state) =&gt; {
          return state.accessToken
      },
      errorState: (state) =&gt; {
          return state.errorState
      },
      errorMessage: (state) =&gt; {
          return state.errorMessage
      },
      isAuthenticated: (state) =&gt; {
          return state.accessToken
      },
      userEmail: (state) =&gt; {
          return state.userEmail
      },
      userPassword: (state) =&gt; {
          return state.userPassword
      },
  }
  </code></pre>
  <p>This is websocket store: I pass the connectionId to the state in order to be able to use it in another vuex action to subscribe for new chats:</p>
  <pre><code>export const namespaced = true
  export const state = {
      connected: false,
      error: null,
      connectionId: '',
      statusCode: '',
      incomingChatInfo: [],
      remoteMessage: [],
      messageType: '',
      ws: null,
  }
  export const actions = {
      processWebsocket({ commit }) {
          const v = this
          this.ws = new WebSocket('mywebsocket')
          this.ws.onopen = function (event) {
              commit('SET_CONNECTION', event.type)
              v.ws.send('message')
          }
          this.ws.onmessage = function (event) {
              commit('SET_REMOTE_DATA', event)
          }
          this.ws.onerror = function (event) {
              console.log('webSocket: on error: ', event)
          }
          this.ws.onclose = function (event) {
              console.log('webSocket: on close: ', event)
              commit('SET_CONNECTION')
              ws = null
              setTimeout(startWebsocket, 5000)
          }
      },
  }
  export const mutations = {
      SET_REMOTE_DATA(state, remoteData) {
          const wsData = JSON.parse(remoteData.data)
          if (wsData.connectionId) {
              state.connectionId = wsData.connectionId
              console.log(`Retrieving Connection ID ${state.connectionId}`)
          } else {
              console.log(`We got chats !!`)
              state.messageType = wsData.type
              state.incomingChatInfo = wsData.documents
          }
      },
      SET_CONNECTION(state, message) {
          if (message == 'open') {
              state.connected = true
          } else state.connected = false
      },
      SET_ERROR(state, error) {
          state.error = error
      },
  }
  </code></pre>
  <p>And finally this is the shift store (where the problem is), as you can see I have a startShift action (everything works fine with it) and then the &quot;updateEventsSubscription&quot; where I'm trying to wait for the response from the &quot;startShift&quot; action and the &quot;processWebsocket&quot; action. Debugging the app I realize that everything works fine with the startShift action but the websocket action sends the response after the &quot;updateEventsSubscription&quot; needs it causing an error when I try to make a put to that API (because it needs the connectionId parameter coming from the state of the websocket).</p>
  <pre><code>import ShiftService from '@/services/ShiftService.js'
  export const namespaced = true
  export const state = {
      connectionId: '',
      shiftId: '',
      agentShiftInfo: '{}',
  }
  export const actions = {
      startShift({ commit }, agentId) {
          return ShiftService.startShift(agentId)
              .then((response) =&gt; {
                  if (response.status === 200) {
                      commit('START_SHIFT', response.data.aggregateId)
                  }
              })
              .catch((error) =&gt; {
                  console.log(error)
                  if (error.response.status === 401) {
                      console.log('Error in Response')
                  }
              })
      },
      async updateEventsSubscription({ dispatch, commit, rootState }, agentId) {
          await dispatch('startShift', agentId)
          const shiftId = state.shiftId
          await dispatch('websocket/processWebsocket', null, { root: true })
          let agentShiftInfo = {
              aggregateId: state.shiftId,
              connectionId: rootState.websocket.connectionId,
          }
          console.log(agentShiftInfo)
          return ShiftService.updateEventsSubscription(shiftId, agentShiftInfo)
              .then((response) =&gt; {
                  commit('UPDATE_EVENTS_SUBSCRIPTION', response.data)
              })
              .catch((error) =&gt; {
                  if (error.response.status === 401) {
                      console.log('Error in Response')
                  }
              })
      },
  }
  export const mutations = {
      START_SHIFT(state, shiftId) {
          state.shiftId = shiftId
          console.log(`Retrieving Shift ID: ${state.shiftId}`)
      },
      UPDATE_EVENTS_SUBSCRIPTION(state, agentShiftInfo) {
          state.agentShiftInfo = agentShiftInfo
      },
  }
  </code></pre>