Utilizing axios in the Vuex store, I am fetching data from an external API that returns an array of objects representing various cities.
Each city object includes a zip code, which is essential for retrieving detailed information about the city. My objective is to append this details-object as a new key within the cities array.
Currently, I employ one Vuex action to fetch all cities and another action specifically for fetching city details.
Action to retrieve all cities
fetchCities: ({ commit, state, dispatch }) => {
let baseUrl = "https://my-url/cities";
let config = {
headers: {
accept: "application/json",
Authorization: ...
},
params: {
param1: "a",
param2: "b"
}
};
axios
.get(baseUrl, config)
.then(function(response) {
commit("UPDATE_CITIES_RAW", response.data.items);
})
.catch(function(error) {
console.log(error);
});
dispatch("fetchCityDetails");
},
Mutation after fetching all cities
UPDATE_CITIES_RAW: (state, payload) => {
state.citiesRaw = payload;
},
Every object in the array contains a zip code, necessary for obtaining city details.
I attempted iterating through the citiesRaw array within the action to fetch details, but encountered an issue where the array was empty at that point due to the action being called before the mutation.
Action to obtain city details
fetchCityDetails: ({ commit, state }) => {
let baseUrl = "https://my-url/cities/";
let config = {
headers: {
accept: "application/json",
Authorization: ...
};
state.citiesRaw.forEach(e => {
let url = baseUrl + e.zipCode;
axios
.get(url, config)
.then(function(response) {
commit("UPDATE_CITY_DETAILS", {
response: response.data,
zipCode: e.zipCode
});
})
.catch(function(error) {
console.log(error);
});
});
},
What are some optimal methods to wait for the initial fetch and then update the array? Is it advisable to manipulate the existing array or create a new one?
Alternatively, are there more effective ways to fetch data based on existing data within the Vuex store?
Update
Following corrections suggested by @Y-Gherbi regarding dispatch timing, I revamped the process of fetching city details:
- The component initiates the
fetchCities
dispatch - In the
fetchCities
action: CommitUPDATE_CITIES
- In the
UPDATE_CITIES
mutation: Utilize .map on the payload to generate new objects and push them intostate.cities
- In the
fetchCities
action: Iterate overstate.cities
and dispatchfetchCityDetails(zipCode)
for each city - In the
fetchCityDetails
action: CommitUPDATE_CITY_DETAILS
- In the
UPDATE_CITY_DETAILS
mutation: Implement .map onstate.cities
to incorporatecityDetails
object for each city
New actions
fetchCities: ({ commit, state, dispatch }) => {
let baseUrl = "https://my-url/cities";
let config = {
headers: {
accept: "application/json",
Authorization: ...
},
params: {
param1: "a",
param2: "b"
}
};
let url = baseUrl;
axios
.get(url, config)
.then(function(response) {
commit("UPDATE_CITIES", response.data.items);
state.cities.forEach(city => {
dispatch("fetchCityDetails", city.zipCode);
});
}
})
.catch(function(error) {
console.log(error);
});
},
fetchCityDetails: ({ commit }, zipCode) => {
let baseUrl = "https://my-url/cities";
let config = {
headers: {
accept: "application/json",
Authorization: ...
},
};
let url = baseUrl + "/" + zipCode;
axios
.get(url, config)
.then(function(response) {
commit("UPDATE_CITY_DETAILS", {
cityDetails: response.data,
zipCode: zipCode
});
})
.catch(function(error) {
console.log(error);
});
}
New mutations
UPDATE_CITIES: (state, cities) => {
// Extracting required data & renaming keys from the response to create new objects
cities = cities.map(city => {
let obj = {};
obj.zipCode = city.zip_code
obj.key1 = city.key_1;
obj.key2 = city.key_2;
return obj;
});
state.cities.push(...cities);
},
UPDATE_CITY_DETAILS: (state, payload) => {
let cities = state.cities;
// Include a details-object for each city
cities = cities.map(city => {
if (city.zipCode == payload.zipCode) {
city.cityDetails = payload.cityDetails;
}
return city;
});
state.cities = cities;
}
Exploring whether there exists a more efficient approach for handling this type of data retrieval.