Vuex-module-decorators: this.whatever is undefined

Created on 10 Sep 2018  路  7Comments  路  Source: championswimmer/vuex-module-decorators

Hi,

I have a module with the following code:

import axios, { AxiosInstance } from "axios";
import { Module, VuexModule, Action, MutationAction, Mutation } from 'vuex-module-decorators'

@Module({ name: 'login', namespaced: true })
export default class LoginModule extends VuexModule {
    loginResult: any;
    backends: Array<string> = [
        'https://192.1686.178.6:8000/',
        'https://localhost:8000/',
        'https://192.168.1.105:8000/',
        'https://192.1686.1.12:8000/'
    ]

    @Action
    async backendLogin() {
        let api: AxiosInstance = axios.create({
            baseURL: this.backends[0]
        });
        let response;

        try {
            response = await api.post("/app/register/", {});
        } catch (ex) {
            console.log(`Error on login: ${ex}`);
        }
        return response;
    }
}

When I try to run this code I get this.backends is undefined, in fact all classproperties are undefined there. Am I missing something?

Most helpful comment

You're not supposed to use state in actions directly, ideally do via a getter.
But yes since it is a possible operation, I will add support for that.

All 7 comments

It seems that when I use this.state.backends it works in the firefox console, but my compiler does not like that syntax:
image

The message is:
Object is possibly 'undefined'.
Property 'backends' does not exist on type 'ThisType<{}> | (() => ThisType<{}>)'.
Property 'backends' does not exist on type 'ThisType<{}>'.

B.t.w. Declaring state in the class does satisfy the compiler:

export default class LoginModule extends VuexModule {
    state: any; // satisfy the compiler and declare state
...
    @Action
    async backendLogin() {
        const baseUrl = this.state.backends[0];
...
}

You're not supposed to use state in actions directly, ideally do via a getter.
But yes since it is a possible operation, I will add support for that.

can you try npm install vuex-module-decorators@beta and see if it is working now ?

Hi,

I'm aware that this issue contains two issues, firstly the one mentioned above that it is not possible to address a state-property in an action.
Using this.backends[0] in my @Action with the provided beta gives the following result:

Uncaught (in promise) Error: ERR_ACTION_ACCESS_UNDEFINED: Are you trying to access this.someMutation() or this.someGetter inside an @Action? 
That works only in dynamic modules. 
If not dynamic use this.context.commit("mutationName", payload) and this.context.getters["getterName"]
Error: Could not perform action backendLogin
    at Store.<anonymous> (http://localhost:8080/vendor.js:23551:33)
    at step (http://localhost:8080/vendor.js:23336:23)
    at Object.next (http://localhost:8080/vendor.js:23317:53)
    at http://localhost:8080/vendor.js:23310:71
    at new Promise (<anonymous>)
    at __awaiter (http://localhost:8080/vendor.js:23306:12)
    at Store.action (http://localhost:8080/vendor.js:23515:20)
    at Array.wrappedActionHandler (http://localhost:8080/vendor.js:24387:23)
    at Store.dispatch (http://localhost:8080/vendor.js:24109:15)
    at Store.boundDispatch [as dispatch] (http://localhost:8080/vendor.js:24015:21)
Error: ERR_STORE_NOT_PROVIDED: To use getModule(), either the module
            should be decorated with store in decorator, i.e. @Module({store: store}) or
            store should be passed when calling getModule(), i.e. getModule(MyModule, this.$store)
    at value (http://localhost:8080/vendor.js:23461:31)
    at getModule (http://localhost:8080/vendor.js:23267:37)
    at Store.<anonymous> (http://localhost:8080/vendor.js:23523:46)
    at step (http://localhost:8080/vendor.js:23336:23)
    at Object.next (http://localhost:8080/vendor.js:23317:53)
    at http://localhost:8080/vendor.js:23310:71
    at new Promise (<anonymous>)
    at __awaiter (http://localhost:8080/vendor.js:23306:12)
    at Store.action (http://localhost:8080/vendor.js:23515:20)
    at Array.wrappedActionHandler (http://localhost:8080/vendor.js:24387:23)
    at Store.<anonymous> (http://localhost:8080/vendor.js:23551:33)
    at step (http://localhost:8080/vendor.js:23336:23)
    at Object.next (http://localhost:8080/vendor.js:23317:53)
    at http://localhost:8080/vendor.js:23310:71
    at new Promise (<anonymous>)
    at __awaiter (http://localhost:8080/vendor.js:23306:12)
    at Store.action (http://localhost:8080/vendor.js:23515:20)
    at Array.wrappedActionHandler (http://localhost:8080/vendor.js:24387:23)
    at Store.dispatch (http://localhost:8080/vendor.js:24109:15)
    at Store.boundDispatch [as dispatch] (http://localhost:8080/vendor.js:24015:21)
Error: ERR_STORE_NOT_PROVIDED: To use getModule(), either the module
            should be decorated with store in decorator, i.e. @Module({store: store}) or
            store should be passed when calling getModule(), i.e. getModule(MyModule, this.$store)
    at value (http://localhost:8080/vendor.js:23461:31)
    at getModule (http://localhost:8080/vendor.js:23267:37)
    at Store.<anonymous> (http://localhost:8080/vendor.js:23523:46)
    at step (http://localhost:8080/vendor.js:23336:23)
    at Object.next (http://localhost:8080/vendor.js:23317:53)
    at http://localhost:8080/vendor.js:23310:71
    at new Promise (<anonymous>)
    at __awaiter (http://localhost:8080/vendor.js:23306:12)
    at Store.action (http://localhost:8080/vendor.js:23515:20)
    at Array.wrappedActionHandler (http://localhost:8080/vendor.js:24387:23)
    at Store.<anonymous> (http://localhost:8080/vendor.js:23545:35)
    at step (http://localhost:8080/vendor.js:23336:23)
    at Object.next (http://localhost:8080/vendor.js:23317:53)
    at http://localhost:8080/vendor.js:23310:71
    at new Promise (<anonymous>)
    at __awaiter (http://localhost:8080/vendor.js:23306:12)
    at Store.action (http://localhost:8080/vendor.js:23515:20)
    at Array.wrappedActionHandler (http://localhost:8080/vendor.js:24387:23)
    at Store.dispatch (http://localhost:8080/vendor.js:24109:15)
    at Store.boundDispatch [as dispatch] (http://localhost:8080/vendor.js:24015:21)
(anonymous) @ vendor.js:23545
step @ vendor.js:23336
(anonymous) @ vendor.js:23317
(anonymous) @ vendor.js:23310
__awaiter @ vendor.js:23306
action @ vendor.js:23515
wrappedActionHandler @ vendor.js:24387
dispatch @ vendor.js:24109
boundDispatch @ vendor.js:24015
local.dispatch @ vendor.js:24317
mappedAction @ vendor.js:24563
click @ Config.vue.ts:109
invoker @ vendor.js:17227
fn._withTask.fn._withTask @ vendor.js:17026
Promise.catch (async)
wrappedActionHandler @ vendor.js:24399
dispatch @ vendor.js:24109
boundDispatch @ vendor.js:24015
local.dispatch @ vendor.js:24317
mappedAction @ vendor.js:24563
click @ Config.vue.ts:109
invoker @ vendor.js:17227
fn._withTask.fn._withTask @ vendor.js:17026

As the error states, this solution will work only with dynamic stores. Or you need to pass the store object to the getModule() call

Error: ERR_STORE_NOT_PROVIDED: To use getModule(), either the module
            should be decorated with store in decorator, i.e. @Module({store: store}) or
            store should be passed when calling getModule(), i.e. getModule(MyModule, this.$store)

Thanks for the help here, it is fixed now (@release 0.8.0-2).
Great work!

ok closing, anyone else who lands on this issue - it'll be in production when 0.8.0 lands into @latest
for now you can use @beta to get this

Was this page helpful?
0 / 5 - 0 ratings

Related issues

cyberflohr picture cyberflohr  路  4Comments

garyo picture garyo  路  5Comments

erathorus picture erathorus  路  5Comments

BonBonSlick picture BonBonSlick  路  5Comments

darthf1 picture darthf1  路  5Comments