Rhodes73
Rhodes73

Reputation: 187

Vuex getter not refreshing with store mutation

I've inherited a VueJs project written in typescript. I have a component which is displaying some data, the vuex store is updated via a mutation (ADD_SCHOOL) but the changes are not reflected in the view. I'm guessing that i need some sort of watcher but i'm not sure what i need to do so that Vue reacts to the change in my Store.

View

data() {
    return {
      school: {} as ISchool
     };
},
async mounted() {
    await this.getSchoolInformation();
},
methods: {
async getSchoolInformation() {
  this.school = await Stores.schoolStore.getSchool(1);
}}}

Store.ts

Vue.use(Vuex);

const modules: ModuleTree<IRootState> = {
  schoolStore: schoolModule
};

const store: Store<IRootState> = new Store<IRootState>({
  modules
});

export default store;

SchoolStore.ts

export default class SchoolStore {
    public async getSchool(id: number, isFirstLoad: boolean): Promise<ISchool> {
        return Store.getters[SchoolNamespace + GetterTypes.GET_SCHOOL_FROM_STORE];
    }
}

School Modules.ts

export const state: ISchoolState = {
  schools: []
};

export const getters: GetterTree<ISchoolState, IRootState> = {
    [GetterTypes.GET_SCHOOL_FROM_STORE]: state => {
    const storeSchool: ISchool | undefined = state.schools.find(x => x.id === 1);
        return storeSchool as ISchool;
    }
};

export const mutations: MutationTree<ISchoolState> = {
    [MutationTypes.ADD_SCHOOL](state: ISchoolState, school: ISchool): void {
    const index: number = state.schools.findIndex(x => x.id === school.id);
    if(index === -1) {
        state.schools.push(school);
    } else {
        state.schools.splice(index, 1, school);
    }}};

const schoolModule: Module<ISchoolState, IRootState> = {
    actions,
    getters,
    mutations,
    namespaced: true,
    state
 };

export default schoolModule;

Index.ts

const schoolStore: SchoolStore = new SchoolStore();

export default {
    schoolStore
};

Upvotes: 3

Views: 2892

Answers (2)

Bruno Francisco
Bruno Francisco

Reputation: 4220

This problem you are having is described in the docs: reactivity in depth

On your mutation you're updating an item in the array or adding a new item to the array. Vue will not pick up that change. For that to work you need to user Vue.set:

import Vue from 'vue'

...

if(index === -1) {
  Vue.set(state.schools, state.schools.length, school);
} else {
  Vue.set(state.schools, index, school);
}}};

Upvotes: 2

Rhodes73
Rhodes73

Reputation: 187

Thanks to Ackroydd i manged to get his working by simplying using a computed property in my View - I also made getSchool synchronous

Updated View

computed: {
    school() {
         return Stores.schoolStore.getSchool(1, false);
    }
  }
});

Upvotes: 2

Related Questions