Advertisement

#40 Defining The Vuex Getters For Our Portfolio Models

In this article we will create several new vuex getters that we can use to retrieve the portfolio categories and plans from our store. Using these getters will allow us to populate the navigation properties of our models automatically anytime we retrieve them from the store.

Code Snippets

portfolio-category-model.ts (1:20)

...
export interface IPortfolioCategoryModelConfig {
    ...
    planId: number;
}

export class PortfolioCategoryModel {
    ...
    private _plan: PortfolioPlanModel | null = null;
    private _planId: number;

    ...
    public get plan() {
        return this._plan;
    }
    public get planId() {
        return this._planId;
    }
    public set planId(planId: number) {
        this._planId = planId;
    }

    constructor(config: IPortfolioCategoryModelConfig) {
        ...
        this._planId = config.planId;
    }
    ...
    public setPlan(plan: PortfolioPlanModel) {
        this._plan = plan;
    }
}
src ⟩ store ⟩ portfolio-category-model.ts

portfolio-initial-state.ts (2:34)

...
if (process.env.NODE_ENV === "development") {
    ...
    const catDelc = new PortfolioCategoryModel({ categoryId: delc.id, id: 1, percent: 38, planId: growth.id });
    const catDemc = new PortfolioCategoryModel({ categoryId: demc.id, id: 2, percent: 12, planId: growth.id });
    const catDesc = new PortfolioCategoryModel({ categoryId: desc.id, id: 3, percent: 6, planId: growth.id });
    const catIedm = new PortfolioCategoryModel({ categoryId: iedm.id, id: 4, percent: 18, planId: growth.id });
    const catIeem = new PortfolioCategoryModel({ categoryId: ieem.id, id: 5, percent: 7, planId: growth.id });
    const catDfdm = new PortfolioCategoryModel({ categoryId: dfdm.id, id: 6, percent: 13, planId: growth.id });
    const catIfdm = new PortfolioCategoryModel({ categoryId: ifdm.id, id: 7, percent: 3, planId: growth.id });
    const catDsdm = new PortfolioCategoryModel({ categoryId: dsdm.id, id: 8, percent: 3, planId: growth.id });
    ...
}
...
src ⟩ store ⟩ portfolio-initial-state.ts

store-constants.ts (3:10)

...
export const GETTER_PORTFOLIO_CATEGORIES = "GETTER_PORTFOLIO_CATEGORIES";
export const GETTER_PORTFOLIO_CATEGORY = "GETTER_PORTFOLIO_CATEGORY";
export const GETTER_PORTFOLIO_PLAN = "GETTER_PORTFOLIO_PLAN";
export const GETTER_PORTFOLIO_PLANS = "GETTER_PORTFOLIO_PLANS";
...
src ⟩ store ⟩ store-constants.ts

portfolio-types.ts (3:42)

import {
    GETTER_PORTFOLIO_CATEGORIES,
    GETTER_PORTFOLIO_CATEGORY,
    GETTER_PORTFOLIO_PLAN,
    GETTER_PORTFOLIO_PLANS,
    ...
} from "@/store";
...
export type GetterPortfolioCategory = (id: number) => PortfolioCategoryModel;
export type GetterPortfolioCategories = (planId: number) => PortfolioCategoryModel[];
export type GetterPortfolioPlan = (id: number) => PortfolioPlanModel;

export interface IPortfolioGetters {
    [GETTER_PORTFOLIO_CATEGORIES]: GetterPortfolioCategories;
    [GETTER_PORTFOLIO_CATEGORY]: GetterPortfolioCategory;
    [GETTER_PORTFOLIO_PLAN]: GetterPortfolioPlan;
    [GETTER_PORTFOLIO_PLANS]: PortfolioPlanModel[];
}
...
src ⟩ store ⟩ portfolio-types.ts

Advertisement

portfolio-module.ts (6:02)

import {
    GETTER_PORTFOLIO_CATEGORIES,
    GETTER_PORTFOLIO_CATEGORY,
    GETTER_PORTFOLIO_PLAN,
    GETTER_PORTFOLIO_PLANS,
    GETTER_SECURITY_CATEGORY,
    ...
} from "@/store/store-constants";

import { findById, undefinedMessage } from "@/store/functions";
...
import { IPortfolioGetters, ... } from "@/store/portfolio-types";
import { StoreActions, StoreActionValidator } from "@/store/store-action-validator";
import { IStoreGetters, StoreGetterTree } from "@/store/store-types";

const storeActionValidator = new StoreActionValidator();

export const portfolioGetters: StoreGetterTree = {
    [GETTER_PORTFOLIO_CATEGORIES]: (storeState, getters: IPortfolioGetters) => {
        return (planId: number) => {
            return storeState[STATE_PORTFOLIO_CATEGORIES].items
                .filter((x) => x.planId === planId)
                .map((x) => getters[GETTER_PORTFOLIO_CATEGORY](x.id));
        };
    },
    [GETTER_PORTFOLIO_CATEGORY]: (storeState, getters: IStoreGetters) => {
        return (id: number) => {
            const state = storeState[STATE_PORTFOLIO_CATEGORIES];
            const portfolioCategory = findById(state, id)!;

            storeActionValidator
                .begin()
                .while(StoreActions.Getting)
                .throwIf(portfolioCategory)
                .isUndefined(undefinedMessage("portfolio category", id, state.index));

            const securityCategory = getters[GETTER_SECURITY_CATEGORY](portfolioCategory.categoryId);

            portfolioCategory.setCategory(securityCategory);

            return portfolioCategory;
        };
    },
    [GETTER_PORTFOLIO_PLAN]: (storeState, getters: IPortfolioGetters) => {
        return (id: number) => {
            const state = storeState[STATE_PORTFOLIO_PLANS];
            const plan = findById(state, id)!;

            storeActionValidator
                .begin()
                .while(StoreActions.Getting)
                .throwIf(plan)
                .isUndefined(undefinedMessage("portfolio plan", id, state.index));

            plan.categories = getters[GETTER_PORTFOLIO_CATEGORIES](plan.id);

            return plan;
        };
    },
    [GETTER_PORTFOLIO_PLANS]: (storeState, getters: IPortfolioGetters) => {
        return storeState[STATE_PORTFOLIO_PLANS].items.map((x) => getters[GETTER_PORTFOLIO_PLAN](x.id));
    },
};
...
src ⟩ store ⟩ portfolio-module.ts

store.ts (14:46)

...
import { portfolioGetters, ... } from "@/store/portfolio-module";
...
const getters = {
    ...
    ...portfolioGetters,
    ...
};
...
src ⟩ store ⟩ store.ts

index.ts (15:09)

...
export * from "@/store/portfolio-category-model";
export * from "@/store/portfolio-plan-model";
export * from "@/store/portfolio-types";
...
src ⟩ store ⟩ index.ts

Planner.vue (15:30)

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";

import { GETTER_PORTFOLIO_PLANS, Getter, PortfolioPlanModel } from "@/store";

@Component
export default class Planner extends Vue {
    @Getter(GETTER_PORTFOLIO_PLANS) private readonly plans!: PortfolioPlanModel[];

    private created() {
        console.log(this.plans);
    }
}
</script>
src ⟩ views ⟩ Planner.vue

Exciton Interactive LLC
Advertisement