Vuex getter fails to update after store mutation

I've recently taken over a VueJs project that was originally written in typescript. There is a component in the project that is responsible for displaying some specific data. The Vuex store gets updated using a mutation called ADD_SCHOOL but the changes are not being reflected in the view. I believe that I might need to implement a watcher of some sort, but I'm unsure about how to make Vue react to the changes happening 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
};

Answer №1

I was able to successfully implement Ackroydd's solution by incorporating a computed property into my View. Additionally, I made the getSchool method synchronous for improved functionality.

Here is the revised View:

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

Answer №2

The issue you are currently facing is clearly outlined in the documentation: deep dive into reactivity

When you make changes to an array by either updating an item or adding a new one, Vue may not detect this change automatically. To ensure proper detection, it is necessary to use Vue.set:

import Vue from 'vue'

...

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

sass-loader in webpack ignoring tsconfig paths

It appears that the Sass-loader is not utilizing the path alias declared in the typescript configuration. When using @use or @import, it results in a "not found" error. Webpack resolve: { plugins: [new TsconfigPathsPlugin()], tsconfig "paths&quo ...

Ways to enhance focus on childNodes using Javascript

I am currently working on implementing a navigation system using a UL HTML Element. Here's the code I have so far: let htmlUL = <HTMLElement>document.getElementById('autocomplete_ul_' + this.name); if (arg.keyCode == 40) { // down a ...

Interactive JS chart for visually representing values within a preset range in Vue.js

I was in need of a custom JavaScript chart specifically designed to display a value within a specified upper and lower limit. The main application for this would be illustrating the current stock price between its 52-week high and low ranges. It was essent ...

Tips on obtaining checkbox values other than "true"

Having trouble retrieving the values of selected checkboxes instead of displaying "Custom Category"? I've attempted to access the values and attributes with no success. I'm aiming to display the values of the selected checkbox. app.component.ht ...

What is the reason that property spreading is effective within Grid components but not in FormControl components?

Explore the sandbox environment here: https://codesandbox.io/s/agitated-ardinghelli-fnoj15?file=/src/temp4.tsx:0-1206. import { FormControl, FormControlProps, Grid, GridProps } from "@mui/material"; interface ICustomControlProps { gridProps?: ...

Common problem encountered with TypeScript is the preference for using import instead of require statements

Is there a correct way to handle the issue of using import over require breaking type checking? Can imports be cast, and are all require's replaceable with import's? https://i.sstatic.net/iihi3.png Left: Property 'get' does not exist. ...

Customize the color of the active button in Bootstrap Vue

I'm currently utilizing bootstrap in conjunction with Vue.js. My form-checkbox-group setup looks like this <b-form-group label="Select flow" v-slot="{ ariaDescribedby }"> <b-form-checkbox-group v-m ...

Is there a way to use Jest to test a Vuex action that contains an API call?

ASYNC ACTION VUEX : Here we have an asynchronous action that is called from the component. It includes a function fetchGaragesData which sends an API request to fetch data from the server. [ACTION_TYPES.FETCH_CASHLESS_GARAGES]: async ( { dispatch ...

What is the best way to access the input element of ng-content from the parent component?

Creating a unique component in the following structure <div class="custom-search-field" [ngClass]="{'expanding': expanding}"> <ng-content></ng-content> </div> When using this component, users are expected to include ...

Reducing SCSS import path in Angular 7

Creating a component that is deeply nested raises the issue of importing shared .scss files with long paths: @import '../../../app.shared.scss'; This hassle doesn't exist when it comes to .ts files, thanks to the configuration in tsconfig. ...

Troubleshooting issues with sorting and pagination in Angular Material table functionality

I am experiencing an issue with sorting and pagination using an Angular material table. The data is being fetched from a store as an observable and successfully displayed in the table. Even though the column names for sorting match the column definitions, ...

Revamping the Meteor project with the latest Bootstrap-4 update

Currently, I am working on a Meteor project that utilizes Bootstrap v3. I am looking to upgrade this project to Bootstrap v4. What specific steps do I need to take in order to accomplish this transition? ...

"Implementing a responsive design with a background image and radial gradient - how to

The image currently in use: https://i.stack.imgur.com/piK6l.jpg Here is how I've implemented it using Vue.js, Bootstrap, and CSS: Code Snippet <div class="landing"> <div class="container text-white details h-100"> ...

Trouble navigating through an index of elastic data? Learn how to smoothly scroll with Typescript in conjunction with

I'm currently using the JavaScript client for Elasticsearch to index and search my data, but I've encountered an issue with using the scroll method. Although I can't seem to set the correct index, I am confident in my technique because I am ...

Encountering an error of ExpressionChangedAfterItHasBeenCheckedError while trying to refresh the

I'm encountering an issue that I need help with: https://i.stack.imgur.com/4M54x.png whenever I attempt to update the view using *ngIf to toggle on an icon display. This is what my .ts file looks like: @Component({ selector: 'app-orders&ap ...

Displaying default value in select dropdown using v-model

I am working on a Vue selectbox with an initial v-model value, and I want to display its value on the selectbox. However, I am unsure of how to accomplish this. Any assistance would be greatly appreciated. new Vue({ el: "#demo", data() { return ...

Error: Unable to execute decodeHtml because it is not recognized as a function

After transitioning to VueJS 2, I encountered a challenge. While using a filter that calls a custom function, I received the error message: TypeError: this.decodeHtml is not a function Below is my code snippet: new Vue({ el: '#modal' ...

The Same Origin Policy has prevented access to the remote resource located at http://localhost:8082/api/countries due to a Cross-Origin Request Block

Solution The XMLHttpRequest access to 'http://localhost:8082/api/countries' from the origin 'http://localhost:4200' has been blocked by the CORS policy. The response to the preflight request is failing the access control check because t ...

How to format a date in ngModel using Angular 9 and above

Is there a way to format the date displayed in my input using ngModel to follow a specific format like 'MM/dd/YYYY'? Can this be achieved by using ngModel? For example, could we do something like model[(ngModel)]="data.targetDate | date:'MM ...

What is the best way to manage an image upload prior to generating the entry for the account in the database?

I am in the process of developing a single page application. For the client side, I have opted to use Nuxt.js, which incorporates Vue.js and Vuex. To handle communication with the server, I'm utilizing axios. The backend API has been constructed us ...