f / f/vue-wait

vuex-module-decorators Integration

Open
#90 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
2k
Forks
98
PR merge metrics
No merged PRs in 30d

Description

Is there a way to integrate this with vuex-module-decorators? mapWaitingActions won't work here since the action ist mapped in by `@Action`.

Example taken from https://blog.logrocket.com/how-to-write-a-vue-js-app-completely-in-typescript/ but with modifications to make it work:
```
npm install vuex-module-decorators -D
npm install vuex-class -D
```
```ts
// store/modules/user.ts
import { VuexModule, Module, Mutation, Action } from 'vuex-module-decorators'
import store from "@/store";

interface IUserState {
name: string
}

@Module({ store: store, namespaced: true })
export default class User extends VuexModule implements IUserState {
public name: string = ''
@Mutation
public setName(newName: string): void {
this.name = newName
}

get nameUpperCase() {
return this.name.toUpperCase();
}

@Action
public updateName(newName: string): void {
this.context.commit('setName', newName)
}
}
export default User
```
```ts
// store.ts
import Vue from 'vue'
import Vuex from 'vuex'
import User from '@/store/modules/user'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
user: User
}
})
export default store
```
```vue


User: {{ nameUpperCase }}


import { Component, Vue } from 'vue-property-decorator'
import { namespace } from 'vuex-class'
const user = namespace('user')
@Component
export default class User extends Vue {
@user.State
public name!: string

@user.Getter
public nameUpperCase!: string

@user.Action
public updateName!: (newName: string) => void
}

```
And a variant of the similar `@MutateAction`:
```ts
// store/modules/user.ts
import {
Module, Mutation, MutationAction,
VuexModule, Action,
} from 'vuex-module-decorators';
import { Veterinarian, VeterinarianControllerApi, VeterinarianSpecialisationEnum } from '@/services';
import { Getter } from 'vuex-class';
import store from '@/store';

interface IUserState {
name: string
}

@Module({ store, namespaced: true })
export default class User extends VuexModule implements IUserState {
public name: string = 'defaultValue'

get nameUpperCase() {
return this.name.toUpperCase();
}

@MutationAction({ mutate: ['name'] })
async updateName(newName: string) {
return { name: newName };
}
}
```
Wrapping the invocation of the Actions would be nice to trigger the wait start and end.

What I tried:
I created my own `WaitingMutationAction` decorator. I just took the original one and wrapped the action with start and end:

WaitingMutationAction

```diff
export interface MutationActionParams {
mutate?: (keyof Partial)[]
rawError?: boolean
root?: boolean
}

-function mutationActionDecoratorFactory(params: MutationActionParams) {
+function waitingMutationActionDecoratorFactory(params: MutationActionParams) {
return function(
target: T,
key: string | symbol,
descriptor: TypedPropertyDescriptor<(...args: any[]) => Promise>>
) {
const module = target.constructor as Mod

const action: Act = async function(
context: ActionContext,
payload: Payload
) {
try {
+ this._vm.$wait.start("test");
const actionPayload = await mutactFunction.call(context, payload)
context.commit(key as string, actionPayload)
} catch (e) {
if (params.rawError) {
throw e
} else {
console.error('Could not perform action ' + key.toString())
console.error(e)
return Promise.reject(e)
}
+ } finally {
+ this._vm.$wait.end("test");
}
}

const mutation: Mut = function(
state: typeof target | Store,
payload: Payload & { [k in keyof T]: any }
}
module.actions![key as string] = params.root ? { root: true, handler: action } : action
module.mutations![key as string] = mutation
}
}

-export function MutationAction(
+export function WaitingMutationAction(
target: { [k in keyof T]: T[k] | null },
key: string | symbol,
descriptor: TypedPropertyDescriptor<(...args: any[]) => Promise>
): void

-export function MutationAction(
+export function WaitingMutationAction(
params: MutationActionParams
): (
target: T,
key: string | symbol,
descriptor: TypedPropertyDescriptor<(...args: any[]) => Promise>
) => void
*
* @param paramsOrTarget the params or the target class
* @param key the name of the function
* @param descriptor the function body
* @constructor
*/
-export function MutationAction(
+export function WaitingMutationAction(
paramsOrTarget: MutationActionParams | M,
key?: string | symbol,
descriptor?: TypedPropertyDescriptor<(...args: any[]) => Promise>>
):
| ((
target: T,
@MutationAction({mutate: ['incrCount']})
async getCountDelta() {
return {incrCount: 5}
}
*
*/
- return mutationActionDecoratorFactory(paramsOrTarget as MutationActionParams)
+ return waitingMutationActionDecoratorFactory(paramsOrTarget as MutationActionParams)
} else {
/*
* This is the case when `paramsOrTarget` is target.
* i.e. when used as -
*

         @MutationAction

async getCountDelta() {
return {incrCount: 5}
}
*

*/
- mutationActionDecoratorFactory({} as MutationActionParams)(
+ waitingMutationActionDecoratorFactory({} as MutationActionParams)(
paramsOrTarget as K,
key!,
descriptor!
)
}
}
```

Well, it works. But it's too much code duplication and dumb.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.