Reputation: 701
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
created
on any of a specified set of pagesi've tried all day to find a solution, but it seems I didn't understand something.
thanks for your help :)
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
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