#34 Creating And Updating Deposits In The Vuex Store
Sunday, January 26, 2020
In this article we will add the ability to create and edit deposits. In addition to being able to change the date and amount of a deposit we will also allow transferring a deposit between accounts.
Parts
- Part 45: Adjusting Shares
- Part 44: Plan Percentages
- Part 43: Home Securities
- Part 42: Updating Plans
- Part 41: Plan Details View
- Part 40: Portfolio Getters
- Part 39: Portfolio Plan
- Part 38: Portfolio Category
- Part 37: Account Securities
- Part 36: Account Transfer
- Part 35: View Account Security
- Part 34: Updating Deposit
- Part 33: View Account Deposit
- Part 32: Display Account Details
- Part 31: Account Getters
- Part 30: Deposits And Securities
- Part 29: Add Accounts Details
- Part 28: Refactoring Accounts
- Part 27: Add Security Models
- Part 26: Edit Security Details
- Part 25: View Security Details
- Part 24: Navigating To Details
- Part 23: Getters Validation
- Part 22: Query Parameters
- Part 21: Tab Entries
- Part 20: Tab Header
- Part 19: List View
- Part 18: Vuex Getters
- Part 17: End Domain Model
- Part 16: Start Domain Model
- Part 15: Pop Routes
- Part 14: Push Routes
- Part 13: Removing Accounts
- Part 12: Vuex (Decorators)
- Part 11: Vuex (Accounts)
- Part 10: The App Bar (Settings)
- Part 9: Remove Consumer Rxjs
- Part 8: The App Bar (Back)
- Part 7: Structuring Our App
- Part 6: Animation Between Views
- Part 5: Navigation Fade
- Part 4: Navigation Requests
- Part 3: Fade Animations (cont.)
- Part 2: Fade Animations
- Part 1: Splash Screen
Code Snippets
store-constants.ts (1:11)
...
...
export const ACTION_ADD_ACCOUNT_DEPOSIT = "ACTION_ADD_ACCOUNT_DEPOSIT";
...
export const ACTION_UPDATE_ACCOUNT_DEPOSIT = "ACTION_UPDATE_ACCOUNT_DEPOSIT";
...
export const MUTATION_ADD_ACCOUNT_DEPOSIT = "MUTATION_ADD_ACCOUNT";
...
export const MUTATION_UPDATE_ACCOUNT_DEPOSIT = "MUTATION_UPDATE_ACCOUNT_DEPOSIT";
...
account-types.ts (2:14)
...
export type PayloadAddAccountDeposit = AccountDepositModel;
...
export type PayloadUpdateAccountDeposit = AccountDepositModel;
...
functions.ts (3:06)
...
interface ISortOptions {
descending?: boolean;
}
...
export function add<T extends IStateItem>(
...
func: (item: T) => string | number,
options?: ISortOptions,
) {
...
state.items = sort([...state.items, item], func, options);
...
}
...
function sortAscending(a: string | number, b: string | number) {
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
}
function sortDescending(a: string | number, b: string | number) {
if (a > b) {
return -1;
}
if (a < b) {
return 1;
}
return 0;
}
export function sort<T>(items: T[], func: (item: T) => string | number, options?: ISortOptions) {
return items.sort((a, b) => {
const funcA = func(a);
const funcB = func(b);
let valueA: string | number;
let valueB: string | number;
if (typeof funcA === "string" && typeof funcB === "string") {
valueA = funcA.toUpperCase();
valueB = funcB.toUpperCase();
} else if (
(typeof funcA === "number" && typeof funcB === "number") ||
(typeof funcA === "bigint" && typeof funcB === "bigint")
) {
valueA = funcA;
valueB = funcB;
} else {
throw new Error(
"The result of calling the provided function must be to convert items into string or numbers.",
);
}
if (
typeof options === "undefined" ||
typeof options.descending === "undefined" ||
options.descending === false
) {
return sortAscending(valueA, valueB);
} else {
return sortDescending(valueA, valueB);
}
});
}
...
Advertisement
account-module.ts (9:37)
...
import moment from "moment";
import {
...
ACTION_ADD_ACCOUNT_DEPOSIT,
...
ACTION_UPDATE_ACCOUNT_DEPOSIT,
...
MUTATION_ADD_ACCOUNT_DEPOSIT,
...
MUTATION_UPDATE_ACCOUNT_DEPOSIT,
...
} from "@/store/store-constants";
import { ... sort, ... } from "@/store/functions";
...
import {
...
PayloadAddAccountDeposit,
...
PayloadUpdateAccountDeposit,
} from "@/store/account-types";
...
export const accountActions: StoreActionTree = {
...
[ACTION_ADD_ACCOUNT_DEPOSIT](this, { commit }, payload: PayloadAddAccountDeposit) {
commit(MUTATION_ADD_ACCOUNT_DEPOSIT, payload);
},
...
[ACTION_UPDATE_ACCOUNT_DEPOSIT](this, { commit }, payload: PayloadUpdateAccountDeposit) {
commit(MUTATION_UPDATE_ACCOUNT_DEPOSIT, payload);
},
};
...
export const accountMutations: StoreMutationTree = {
...
[MUTATION_ADD_ACCOUNT_DEPOSIT](storeState, payload: PayloadAddAccountDeposit) {
add(storeState[STATE_ACCOUNTS_DEPOSITS], payload, (x) => moment(x.date).valueOf(), { descending: true });
},
...
[MUTATION_UPDATE_ACCOUNT_DEPOSIT](storeState, payload: PayloadUpdateAccountDeposit) {
const state = storeState[STATE_ACCOUNTS_DEPOSITS];
const deposit = findById(state, payload.id)!;
storeActionValidator
.begin()
.while(StoreActions.Updating)
.throwIf(deposit)
.isUndefined(undefinedMessage("deposit", payload.id, state.index));
deposit.accountId = payload.accountId;
deposit.amount = payload.amount;
deposit.date = payload.date;
state.items = sort(state.items, (x) => moment(x.date).valueOf(), { descending: true });
},
};
...
AccountsDeposit.vue (15:37)
<script lang="ts">
...
import {
...
ACTION_ADD_ACCOUNT_DEPOSIT,
...
ACTION_UPDATE_ACCOUNT_DEPOSIT,
...
PayloadAddAccountDeposit,
...
PayloadUpdateAccountDeposit,
} from "@/store";
...
export default class AccountsDeposit extends Vue {
@Action(ACTION_ADD_ACCOUNT_DEPOSIT) private readonly addDeposit!: ActionFn<PayloadAddAccountDeposit>;
...
@Action(ACTION_UPDATE_ACCOUNT_DEPOSIT) private readonly updateDeposit!: ActionFn<PayloadUpdateAccountDeposit>;
...
private save() {
const deposit = new AccountDepositModel({
accountId: this.accountId,
amount: this.amount,
date: moment(this.date).toDate(),
id: this.id,
});
switch (this.id) {
case 0:
this.addDeposit(deposit);
return;
default:
this.updateDeposit(deposit);
return;
}
}
}
</script>
AccountsDeposit.vue (19:56)
<script lang="ts">
...
import {
...
AccountModel,
...
GETTER_ACCOUNTS,
...
} from "@/store";
...
export default class AccountsDeposit extends Vue {
...
@Getter(GETTER_ACCOUNTS) private readonly accounts!: AccountModel[];
...
private accountName = "";
...
private transfer = false;
...
private load(deposit: AccountDepositModel) {
...
this.accountName = deposit.account.name;
...
}
...
private toggleTransfer() {
this.transfer = !this.transfer;
}
}
</script>
AccountsDeposit.vue (21:55)
<template lang="pug">
form
div.inputs
h1 Deposit
label
span Account
small
a(v-on:click.prevent="toggleTransfer")
span(v-if="!transfer") Transfer
span(v-if="transfer") Cancel
div.transfer-inputs
div.transfer-from
label(v-if="transfer") From
div.input {{accountName}}
div.transfer-to(v-if="transfer")
label To
select(
v-model="accountId")
option(
v-for="account in accounts"
v-bind:key="account.id"
v-bind:value="account.id") {{account.name}}
...
...
</template>
AccountsDeposit.vue (26:15)
<style lang="sass" scoped>
...
.transfer-inputs
display: flex
> *
flex: 1
.transfer-from
margin-right: 0.125rem
.transfer-to
margin-left: 0.125rem
</style>
Exciton Interactive LLC