Cannot get Vuex state on async created

193 Views Asked by At

I have the following Vue component (based on the HelloWorld example)

<template>
  <div class="hello">
     <h1>Message: {{ post.title }} </h1>
      <button @click="refreshPost">Refresh</button>
  </div>
</template>

<script lang="ts">
    import {Component, Vue, Prop, } from 'vue-property-decorator';
    import {IPostModel} from "@/models/IPostModel";
    import {namespace} from "vuex-class";
    const postStore = namespace('Post')

@Component
export default class HelloWorld extends Vue {

    @postStore.State
    public post!: IPostModel

    @postStore.Action
    public refreshPost!: Promise<IPostModel>

    async created(){
        console.log("starting created");
        await this.refreshPost;
        console.log("finished created");
    }
}
</script>

And the corresponding Vuex module

import axios from 'axios'
import { VuexModule, Module, Mutation, Action } from "vuex-module-decorators";
import { IPostModel } from "@/models/IPostModel";

@Module({namespaced: true })
class Post extends VuexModule{

  public post: IPostModel = { id: -1, userId: -1, title: ''}

  @Mutation
  private setPost(newPost: IPostModel): void{
    this.post = newPost;
  }

  @Action({rawError: true})
  public async refreshPost(): Promise<IPostModel> {
    const response = await axios.get('https://jsonplaceholder.typicode.com/posts/1');
    this.context.commit('setPost', response.data);
    return response.data;
  }
}

export default Post

The code to call the api works fine when I click the refresh button, but doesn't appear to set the state on the created hook and I can't figure out why. I've tried various combinations of Promise & await & async and it either errors or makes no difference.

1

There are 1 best solutions below

4
On

You are missing some steps. Let's call the Vuex module, VuexModule

In your VuexModule, add a namespace name

@Module({ namespaced: true, name: 'Post' }) // add name

import { namespace } from 'vuex-class';
import { getModule } from 'vuex-module-decorators';

import VuexModule from '@/store/modules/vuexmodule.ts'; //module which has 'Post' as namespace

const postStore = namespace('Post')

let vuexModule: VuexModule;

export default class HelloWorld extends Vue {
  async created() {
    vuexModule = getModule(VuexModule, this.$store);
    await vuexModule.refreshPost();
  }
}

You can learn more in this excellent article