Search code examples
vue.jsvuexpollinglong-polling

Long polling in Vue.js and Vuex that's independent of components' lifecycle, where to store hot observables for "unsubscribe"?


Problem: Having started multiple long-polling streams that need to persist throughout the app lifecycle (regardless of the lifecycle of individual components), I'm looking for a way to unsubscribe in response to various events (e.g. route change, but not limited to). To that end I wrote the following code:

export const actions: ActionTree<TasksState, RootState> = {
  async pollEventTasks({ dispatch, commit, state, rootState }, payload: any) {

    const pollEventTasks$ = timer(0, 5000).pipe(
      switchMap(_ => tasksService.loadTasksForEvent(payload.eventId)),
      map((response: any) => {
        commit('setTasks', response);
      })
    ).subscribe();

    // this won't work in strict mode. Hot observables ~can't~ shouldn't be written to store:
    // commit('longPolling/eventTasksPollingStarted', pollEventTasks$, {root: true});
  },

A hot observable "updates itself", thus mutating store outside of mutation handler. What would be a neat solution fitting vue/vuex best practices?


Solution

  • We ended up building a plugin injected via Vue.use and storing Observable subscriptions there