vuex-class-component icon indicating copy to clipboard operation
vuex-class-component copied to clipboard

Feature request: create proxy inside of VuexModule

Open cmeyertons opened this issue 5 years ago • 3 comments

Wow this library is fantastic -- makes working with vuex modules much more intuitive and easy to use w/ type safety and intellisense!

The first module I implemented had to call out to another module that houses same shared logic, so I implemented using the raw action context, which worked but I lost all the type safety

import { VuexModule, Module, getter, action, getRawActionContext, mutation } from 'vuex-class-component';
import RootState from '../../types/RootState'
import Product from '../../types/product/Product';
import bodybuilder from 'bodybuilder';

export interface SubscriptionState {
  subscriptions: Product[] | [],
}

@Module({ namespacedPath: 'subscriptions/' })
export class SubscriptionStore extends VuexModule {
  @getter items: Product[] = []

  @mutation
  loadItems (items: Product[]) {
    this.items = items
  }

  @action({ mode: 'raw'})
  load (): Promise<void> {
    const context = getRawActionContext(this)
    const query = bodybuilder()
      .query('match', 'category.name', 'Subscriptions')
      .build()

    return context.dispatch('product/list', { query, start: 0, size: 10, updateState: false }, { root: true }).then(resp => {
      const subscriptions = (resp.items as Product[]).sort((p1, p2) => +p1.order - (+p2.order))
      context.commit('loadItems', subscriptions)
    }).catch((err) => {
      console.error(err)
    })
  }
}

Would it be possible to create a proxy that takes a VuexModule as a constructor? So inside my subscription vuex module it would look like:

product = ProductStore.CreateProxy(ProductStore, this)

Could that proxy method leverage the raw context to generate the necessary proxy? And then you have all the type safety you need when dispatching an action to another module

cmeyertons avatar May 06 '19 12:05 cmeyertons

@cmeyertons With #23 you can create a proxy from inside your actions, like so:

@Module({ namespacedPath: 'subscriptions/' })
export class SubscriptionStore extends VuexModule {
  @getter items: Product[] = []

  @mutation
  loadItems (items: Product[]) {
    this.items = items
  }

  @action
  load (): Promise<void> {
    const productStore = ProductStore.CreateProxy(this.$store, ProductStore)
    const query = bodybuilder()
      .query('match', 'category.name', 'Subscriptions')
      .build()
    return productStore.list({query, start: 0, size: 10, updateState: false }}
        .then(resp => {
      const subscriptions = (resp.items as Product[]).sort((p1, p2) => +p1.order - (+p2.order))
      this.loadItems(subscriptions)
    }).catch((err) => {
      console.error(err)
    })
  }
}

asmadsen avatar May 08 '19 14:05 asmadsen

awesome! do you happen to know what version this will be released in?

cmeyertons avatar May 17 '19 12:05 cmeyertons

I'm pretty sure it's already in the latest version

asmadsen avatar May 17 '19 13:05 asmadsen