devman
devman

Reputation: 701

Using one vuex module store in multiple sibling components

I have one global state with some modules.

now i have vue components for various parts of my page.

i have everything setup so /foo uses the foo store (this works). the created method loads data from an API and writes it to the store

now i have /foo/bar as another (sibling) component, but it needs to access the same store as /foo, but i can't get it to work.

if i enter /foo/bar/ in the URL, there is nothing in the store. but if i switch to /foo, and then back to /foo/bar, the data is in the store and being output correctly

I've tried registering /foo/bar as a child, which seemed to have no effect (and actually it's not really a child, but just another page with the same data..)

I also tried

state: {
    ...mapState([
        'foo'
    )]
}

in /foo/bar, but that doesn't seem to be the right way either

what is the best practice to

  1. load data from API on created on any of a specified set of pages
  2. access said data on any of those pages (i.e. sharing the same store)

i've tried all day to find a solution, but it seems I didn't understand something.

thanks for your help :)

EDIT

actually, while i read my question again, i think my whole problem is the data not being loaded (because the created method is not called). how can i make sure this happens on any page using the store and just once? i can't just write an api call in every created method, can i?

Upvotes: 2

Views: 2372

Answers (1)

Juan Rivillas
Juan Rivillas

Reputation: 957

Well, I think just to summarize your problem could be called like you're not being able to access the same state between two different componentes.

What I do normally is that I make an API call from one component inside the method beforeMount, that will guarantee that once my component is created, the data will be available to be used.

Furthermore, after calling the api, I update my state so after that I can call it from everywhere.

One thing that you have to take care with is which component is loaded first?

If A is B's parent, then you should load data inside A. However, if A and B are siblings, then you should load data inside both of them because you can access first either Component A or B, then you don't know when the data is going to be available. In that case, I would load the data in both of the components. Also, add cache to your server so you don't need to load the same data again.

For example:

State

{
  data: {}
}

Component A

export default {
  name: 'Batch',
  beforeMount() {
    this.getDataFromAPI();
  },
  methods: {
    // getDataFromAPI will store its return inside data with a mutation
    ...mapActions(['getDataFromAPI']),
    randomMethod() {
      // Now I can Use my state
      const data = this.$store.state.data;
    }
  }
};

Component B

export default {
  name: 'Batch',
  methods: {
    randomMethodB() {
      // If component A was loaded first than component B and A is B's parent, then the state will be accessible in the same manner and it should be populated
      const data = this.$store.state.data;
    }
  }
};

Actions

const getDataFromAPI = ({ commit }) => new Promise((resolve, reject) => { 

  // Call server
  const data = await callServer();
  commit('updateMyStateWithData');
  resolve(data);

});

export default {
  getDataFromAPI
}

Mutations

const mutations = {
  updateMyStateWithData(state, newData) {
    state.data = newData;
  }
}

export default mutations;

Another thing that I do is to define getters, that way is a good approach to load data once, and inside the getter you update the data to return only the things that your UI needs.

I hope that it helps!

Upvotes: 2

Related Questions