Advertisement

#37 Creating And Updating Account Securities In The Vuex Store

In this article we will implement the ability to add, update and transfer account securities from one account to another. Along the way we will need to change the way we get the account securities to account for wanting them to be sorted alphabetically by the symbol of the security. We will also need to handle a few complications related to transferring an account security from one account to another.

Code Snippets

store-constants.ts (1:31)


...
export const ACTION_ADD_ACCOUNT_SECURITY = "ACTION_ADD_ACCOUNT_SECURITY";
...
export const ACTION_UPDATE_ACCOUNT_SECURITY = "ACTION_UPDATE_ACCOUNT_SECURITY";
...
export const MUTATION_ADD_ACCOUNT_SECURITY = "MUTATION_ADD_ACCOUNT_SECURITY";
...
export const MUTATION_UPDATE_ACCOUNT_SECURITY = "MUTATION_UPDATE_ACCOUNT_SECURITY";
...
src ⟩ store ⟩ store-constants.ts

account-types.ts (2:36)

...
export type PayloadAddAccountSecurity = AccountSecurityModel;
...
export type PayloadUpdateAccountSecurity = AccountSecurityModel;
...
src ⟩ store ⟩ account-types.ts

functions.ts (3:26)

...
export function add<T extends IStateItem>(
    ...
    func?: (item: T) => string | number,
    ...
) {
    ...
    const items = [...state.items, item];
    if (typeof func !== "undefined") {
        state.items = sort(items, func, options);
    } else {
        state.items = items;
    }
    ...
}
...
src ⟩ store ⟩ functions.ts

account-module.ts (5:04)

...
import {
    ...
    ACTION_ADD_ACCOUNT_SECURITY,
    ...
    ACTION_UPDATE_ACCOUNT_SECURITY,
    ...
    MUTATION_ADD_ACCOUNT_SECURITY,
    ...
    MUTATION_UPDATE_ACCOUNT_SECURITY,
    ...
} from "@/store/store-constants";
...
import {
    ...
    PayloadAddAccountSecurity,
    ...
    PayloadUpdateAccountSecurity,
} from "@/store/account-types";
...
export const accountActions: StoreActionTree = {
    ...
    [ACTION_ADD_ACCOUNT_SECURITY](this, { commit }, payload: PayloadAddAccountSecurity) {
        commit(MUTATION_ADD_ACCOUNT_SECURITY, payload);
    },
    ...
    [ACTION_UPDATE_ACCOUNT_SECURITY](this, { commit }, payload: PayloadUpdateAccountSecurity) {
        commit(MUTATION_UPDATE_ACCOUNT_SECURITY, payload);
    },
};
...
export const accountMutations: StoreMutationTree = {
    ...
    [MUTATION_ADD_ACCOUNT_SECURITY](storeState, payload: PayloadAddAccountSecurity) {
        add(storeState[STATE_ACCOUNTS_SECURITIES], payload);
    },
    ...
    [MUTATION_UPDATE_ACCOUNT_SECURITY](storeState, payload: PayloadUpdateAccountSecurity) {
        const state = storeState[STATE_ACCOUNTS_SECURITIES];
        const security = findById(state, payload.id)!;

        storeActionValidator
            .begin()
            .while(StoreActions.Updating)
            .throwIf(security)
            .isUndefined(undefinedMessage("security", payload.id, state.index));

        security.accountId = payload.accountId;
        security.securityId = payload.securityId;
        security.shares = payload.shares;

        state.items = [...state.items];
    },
};
...
src ⟩ store ⟩ account-module.ts

Advertisement

AccountsSecurity.vue (10:21)

<script lang="ts">
...
import {
    AccountSecurityModel,
    ...
    ACTION_ADD_ACCOUNT_SECURITY,
    ...
    ACTION_UPDATE_ACCOUNT_SECURITY,
    ...
    PayloadAddAccountSecurity,
    ...
    PayloadUpdateAccountSecurity,
    ...
} from "@/store";
...
export default class AccountsSecurity extends Vue {
    @Action(ACTION_ADD_ACCOUNT_SECURITY) private readonly addSecurity!: ActionFn<PayloadAddAccountSecurity>;
    ...
    @Action(ACTION_UPDATE_ACCOUNT_SECURITY) private readonly updateSecurity!: ActionFn<PayloadUpdateAccountSecurity>;
    ...
    private save() {
        const accountSecurity = new AccountSecurityModel({
            accountId: this.accountId,
            id: this.id,
            securityId: this.securityId,
            shares: this.shares,
        });
        switch(this.id) {
            case 0:
                this.addSecurity(accountSecurity);
                return;
            default:
                this.updateSecurity(accountSecurity);
                return;
        }
    }
}
</script>
src ⟩ views ⟩ AccountsSecurity.vue

account-module.ts (16:39)

...
export const accountActions: StoreActionTree = {
    ...
    [ACTION_ADD_ACCOUNT_SECURITY](this, { commit }, payload: PayloadAddAccountSecurity) {
        const state = this.state[STATE_ACCOUNTS_SECURITIES];
        const accountSecurity = state.items.find(
            (x) => x.accountId === payload.accountId && x.securityId === payload.securityId,
        );
        if (typeof accountSecurity === "undefined") {
            commit(MUTATION_ADD_ACCOUNT_SECURITY, payload);
        } else {
            payload.id = accountSecurity.id;
            payload.shares += accountSecurity.shares;
            commit(MUTATION_UPDATE_ACCOUNT_SECURITY, payload);
        }
    },
    ...
};
...
export const accountGetters: StoreGetterTree = {
    ...
    [GETTER_ACCOUNT_SECURITIES]: (storeState, getters: IStoreGetters) => {
        return (accountId: number) => {
            ...
            const sorted = sort(accountSecurities, (x) => x.security.symbol);

            return sorted;
        };
    },
    ...
};
...
src ⟩ store ⟩ account-module.ts

store-constants.ts (20:18)

...
export const ACTION_REMOVE_ACCOUNT_SECURITY = "ACTION_REMOVE_ACCOUNT_SECURITY";
...
export const MUTATION_REMOVE_ACCOUNT_SECURITY = "MUTATION_REMOVE_ACCOUNT_SECURITY";
...
src ⟩ store ⟩ store-constants.ts

account-types.ts

...
export type PayloadRemoveAccountSecurity = AccountSecurityModel;
...
src ⟩ store ⟩ account-types.ts

account-module.ts (20:40)

...
import {
    ...
    ACTION_REMOVE_ACCOUNT_SECURITY,
    ...
    MUTATION_REMOVE_ACCOUNT_SECURITY,
    ...
} from "@/store/store-constants";
...
import {
    ...
    PayloadRemoveAccountSecurity,
    ...
} from "@/store/account-types";
...
export const accountActions: StoreActionTree = {
    ...
    [ACTION_REMOVE_ACCOUNT_SECURITY](this, { commit }, payload: PayloadRemoveAccountSecurity) {
        commit(MUTATION_REMOVE_ACCOUNT_SECURITY, payload);
    },
    ...
    [ACTION_UPDATE_ACCOUNT_SECURITY](this, { commit }, payload: PayloadUpdateAccountSecurity) {
        const state = this.state[STATE_ACCOUNTS_SECURITIES];
        const accountSecurity = state.items.find(
            (x) => x.accountId === payload.accountId && x.securityId === payload.securityId,
        );
        if (typeof accountSecurity !== "undefined" && accountSecurity.id !== payload.id) {
            commit(MUTATION_REMOVE_ACCOUNT_SECURITY, payload);
            payload.id = accountSecurity.id;
            payload.shares += accountSecurity.shares;
        }
        commit(MUTATION_UPDATE_ACCOUNT_SECURITY, payload);
    },
};
...
export const accountMutations: StoreMutationTree = {
    ...
    [MUTATION_REMOVE_ACCOUNT_SECURITY](storeState, payload: PayloadRemoveAccountSecurity) {
        storeState[STATE_ACCOUNTS_SECURITIES].items = storeState[STATE_ACCOUNTS_SECURITIES].items.filter(
            (x) => x.id !== payload.id,
        );
    },
    ...
};
...
src ⟩ store ⟩ account-module.ts

Exciton Interactive LLC
Advertisement