5
votes

When I put this in my Vue component ...

// using store getter

computed: {
  authenticated() {
    return this.$store.getters.authenticated
  }
}

... it works. The value for authenticated is reactive and the computed property returns true when the value in the vuex store is true.

This should work ... (and would be the right way according to the docs)

// using store state

computed: {
  authenticated() {
    return this.$store.state.authenticated
  }
}

... but doesn't. The computed property is always false.

It doesn't even work on initial state, so I guess it has nothing to do with the action or mutation. The vuex store holds the correct values in the state and the getters (Firefox Vue DevTools).

My store looks like this:

const state = {
    authenticated: authenticate.isAuthenticated(),
};

const getters = {
    authenticated () {
        return state.authenticated
    }
};

const mutations = {
    isAuthenticated (state, isAuthenticated) {
        state.authenticated = isAuthenticated
    }
};

So, it works with store getters but not with store state. Afaik the store state should be reactive as well.

Any idea what I might be doing wrong?

3
What does it do? "Doesn't work" is vague.Roy J
Getters accept state as a parameter. Your getter should be authenticated(state) {return state.authenticated}.Bert
Do you export the state alongside with the getters,actions and mutators?Sletheren
@RoyJ you are right, I updated the question and hope the problem is clearer now.Rico Leuthold
@Sletheren yes I do.Rico Leuthold

3 Answers

3
votes

More as an aside to this discussion, vuex offers the mapGetters, mapState, mapActions, and mapMutations helper functions.

In the case of the authenticated getter, you would map it like:

import { mapGetters } from 'vuex

computed: {
    ...mapGetters({
        authenticated: 'authenticated'
    })
}

Helps to keep your code clean and concise, imo.

1
votes

Assuming you construct your Vuex.Store as I do below, the computed works as expected using either state.authenticated or getters.authenticated.

The mutations section made no difference, so I took it out to make things minimal.

As Bert noted, your getter should take state as a parameter; otherwise, it is using the declared const, which is the same thing in this case, but deceptive to read.

const authenticate = {
  isAuthenticated() {
    return true;
  }
};

const state = {
    authenticated: authenticate.isAuthenticated()
};

const getters = {
    authenticated (state) {
        return state.authenticated;
    }
};

const store = new Vuex.Store({
  state,
  getters
});

new Vue({
  el: '#app',
  store,
  computed: {
    authenticated() {
      return this.$store.state.authenticated;
    }
  }
});
<script src="//unpkg.com/vue@latest/dist/vue.js"></script>
<script src="//unpkg.com/vuex@latest/dist/vuex.js"></script>
<div id="app">
  Anything? {{authenticated}}
</div>
0
votes
const state = {
   authenticated: authenticate.isAuthenticated(),
};

The state is an object. An attribute in the object is trying to call the result of a function. This might be the problem, as it would be asking an object to invoke functions. Try setting it to a fixed value first, and change the state value by invoking a mutation when needed.

You could also try js object function call to invoke the authenticate.isAuthenticated() function inside the state object. Details here: https://www.w3schools.com/js/js_function_call.asp

Possible solution:

const state = {
   authenticated: function(){ return authenticate.isAuthenticated() },
};