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

How to access Store extensions in 'this' instance?

Open Arsync opened this issue 5 years ago • 2 comments

Within vanilla Vuex we have extension like

// vuex-shims.d.ts
declare module 'vuex/types' {
    interface Store<S> {
        $api: ServiceFactory;
    }
}

And access it in actions like

async [ActionNames.DoSomething]() {
  await this.$api.doSomething(); // 'this' known as Store<R> type and $api is registered extension.
}

But module of 'vuex-class-modules' has no 'this' as Store type. How to access $api extension?

Tried to make extended subclass of VuexModule like

export class AugmentedVuexModule extends VuexModule
{
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    protected store: Store<any>;

    constructor(options: RegisterOptions)
    {
        super(options);
        this.store = options.store;
    }
}

Usage:

@Action
async doSomething()
{
    await this.store.$api.doSomething();
}

But it cause an error:

/ -> error during render
RangeError: Maximum call stack size exceeded

Arsync avatar Aug 26 '20 13:08 Arsync

I would propose that you provide the service factory directly to your vuex class module:

@Module
class MyModule extends VuexModule {
  constructor(private api: ServiceFactory, options: RegisterOptions) {
    super(options);
  }
}

export const myModule = new MyModule(api, { store, name: "myModule" });

Yes, that means you have to explicitely provide the service factory to every module that needs it. This approach works well with dependency injection (e.g. InversifyJS) though.

bodograumann avatar Aug 26 '20 13:08 bodograumann

Something wrong with this implementation:

@Module
export default class EmployeeProfileModule extends VuexModule
{
    private api: ServiceFactory; // Works fine, while 'identity' field commented

    private identity: IdentityManager; // <-- this one cause RangeError: Maximum call stack size exceeded

    constructor(
        api: ServiceFactory,
        identity: IdentityManager,
        options: RegisterOptions
    )
    {
        super(options);

        this.api = api;
        this.identity = identity;
    }
}

If we add DI parameter of 'IdentityManager', it cause

RangeError: Maximum call stack size exceeded
    at Function.keys (<anonymous>)
    at _traverse ... vue\dist\vue.runtime.common.dev.js:2117:19

Arsync avatar Aug 26 '20 16:08 Arsync