r239rj928
r239rj928

Reputation: 1

Correct usage of getters in vuex

I'm currently developing an app with vue v2, and something got me thinking. It's kind of hard to find information for good practices so I decided I will ask here.

I have a laravel api and vue for front end. Until now my models were such that will hold only a few objects (< 100), so I just put the in the state, and get what ever needed with a getter. Now I have a model that will hold > 10000 objects, so putting them all into the state is pretty much out the topic. The way I solve this problem is a have with action that gets a single object from the api by id, and put it in the state, after a check if its not in there already. The check happens with a getter that I'm also using when I need this object. So I have similar structure:

// mutation
[mutation_types.FETCH_SOMETHING](state, {something}) {
    if (!this.getters.getSomethingById(something.id)) {
        state.somethings.push(something)
    }
}

// action
const {data} = await axios.get('~route~')
commit(mutation_types.FETCH_SOMETHING, {something: data.something})

// getter
getSomethingById: state => id => {
    return state.somethings.find(something => something.id === id)
}

So this is working, but there are 2 problems that I see. The first is every time when I need a something I should call the dispatch to get the item from the api into the state and then the getter to get the actual object and the second problem is the check is happening after the api call, so even if I have this specific something in the state, I'm doing a request for it.

A way to fix both of those problems that I though of calling the just working with the getter, which will check that state, if the searched ID is found in there it will be returned, if not, the dispatch will get it from the api and then return it.

I feel like I'm adding logic to the getter that doesn't belong there, but I can't think of another way to achieve this. Is there something that I'm missing / doing wrong somewhere?

Upvotes: 0

Views: 81

Answers (1)

Brian Lee
Brian Lee

Reputation: 18187

Take advantage of the async nature of vuex actions and promises. Do the check for existence directly in the action along with the api call if needed:

state: {
  items: []
}

mutations: {
  addItem: (state, item) => {
    state.items.push(item)
  }
}

actions: {
  fetchItem: async (context, id) => {
    let item = context.state.items.find(i => i.id === id)
    if (!item) {
      item = await axios.get('/example/' + id).then(response => {
        context.state.commit('addItem', response.data)
        return response.data
      })
    }
    return item
  }
}

Upvotes: 1

Related Questions