2

I want to loop over an array of objects using v-for. However my state returns an object containing an array of Objects:

{ "todos": [ { "id": "x", "description": "y" }, { "id": "a", "description": "b" } ] }

which causes v-for not to work. If I use a getter instead it returns my array of objects like it's supposed to:

[ { "id": "x", "description": "y" }, { "id": "a", "description": "b" } ]

is this normal behaviour?

using mapState:

<template>
    <div class="content-center">
       {{todos}}   
    </div>
</template>
....
import {mapActions, mapGetters, mapState} from 'vuex';

  export default {
        ....
        computed: mapState(['todos'])
    }

using getter:

<template>
    <div class="content-center">
       {{getTodos}}   
    </div>
</template>
....
import {mapActions, mapGetters, mapState} from 'vuex';

 export default {
        ....
        computed: mapGetters(['getTodos'])
    }

I also wanna add that i'm using modules, in case that changes anything about calling the mapState

vuex:

const state = {
    todos: []
};

const getters = {

    getTodos: state => state.todos

};

const actions = {
    loadTodos({commit}) {
        axios.get('/api/todos', {
        }).then(response => {
            commit('setTodos', response.data);
        }).catch(error => {
            console.error(error);
        })
    }
};

const mutations = {
    setTodos: (state, response) => {
        state.todos = response;
    }
};
4
  • 2
    show how you use mapState and a getter
    – Anatoly
    Commented May 11, 2020 at 13:51
  • @Anatoly updated my question
    – Rugo
    Commented May 11, 2020 at 14:01
  • 1
    can you share your vuex relevant code as well
    – depperm
    Commented May 11, 2020 at 14:12
  • @depperm added :)
    – Rugo
    Commented May 11, 2020 at 14:16

3 Answers 3

2

According to the Vuex documentation, the mapState helper returns an object by default.

The reason why your getter returns an array instead of an object is that a getter must always be a function. In your case, the single line arrow function state => state.todos accesses the object and it then implicitly returns the state within the object.

Instead of passing a string array into the helper like mapState(['todos']), you can open it up to perform additional operations (i.e. to access the object) as shown in the docs:

computed: mapState({
        todos: state => state.todos
})

Notice that you are basically accessing the state the same way the getter was... Only this time you're doing it within the component under the computed section.

Note: If you have nested modules, you might want to bind your namespaces as shown in the docs here.

Additionally, if you don't need to make use of multiple store state properties or getters, then you could just access that single todos property using the this.$store shortcut:

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

Hope that helps.

1

Making my modules namespaced fixed the problem, even though I'm not quite sure why.

1

Making my modules namespaced fixed the problem, even though I'm not quite sure why.

Only actions, mutations, and getters get registered in the global namespace, not module state. Found here Therefore namespacing solved your issue.

Still you can use mapState without namespacing like this:

computed: { 
    ...mapState({
      todos: state => state.FilenameOfYourModule.todos
    })
}

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.