I am aiming to have a state in my Vuex store which gets populated on initial app load with data from an external API as follows:
import axios from 'axios'
export const state = () => ({
airports: [],
pairing: {
departure: null,
arrival: null
},
loading: false
})
export const getters = {
getAirports: (state) => {
return state.airports
}
}
export const mutations = {
SET_AIRPORTS(state, payload) {
state.airports = payload
},
SET_LOADING(state, payload) {
state.loading = payload
},
SET_AIRPORT(state, { airport, type }) {
state.pairing[type] = airport
},
CLEAR_AIRPORT(state, type) {
state.pairing[type] = null
}
}
export const actions = {
loadAirports({ commit }) {
commit('SET_LOADING', true)
axios.get('https://raw.githubusercontent.com/jpatokal/openflights/master/data/airports.dat')
.then(response => {
// Get each row of data from the source
const rows = response.data.split('\n');
// Convert data from row to object
const airports = rows.map(row => {
// Parse the comma-separated fields from the line by using
const fields = row.split(',')
.map(x => x.replace(/(^"|"$)/g, ''));
return {
id: fields[0],
name: fields[1],
city: fields[2],
country: fields[3],
iata: fields[4],
icao: fields[5],
longitude: fields[6],
latitude: fields[7],
};
});
commit('SET_AIRPORTS', airports)
commit('SET_LOADING', false)
})
},
}
Usually I would just dispatch the loadAirports
action in the App.vue when working with Vue.js standalone. However, as I am building my app in Nuxt.js I cannot seem to figure out how to load the data to my state without dispatching this method in every page I create but rather just once on app load.
Any suggestions?
CodePudding user response:
If you have an action called nuxtServerInit
in universal mode, Nuxt will call it with the Nuxt context. You can use this function to load data or dispatch other actions:
const actions = {
nuxtServerInit({ dispatch }, ctx) {
dispatch('loadAirports');
}
}
Note that nuxtServerInit
is only called server side (or during compile-time if statically generating). You can implement a similar nuxtClientInit
by creating a client plugin that immediately dispatches to the store.
https://nuxtjs.org/docs/directory-structure/store/#the-nuxtserverinit-action
CodePudding user response:
This is actually quite simple to do in NuxtJs.
First of all define your initial state:
export const state = () => ({
airports: [],
})
Since Nuxt gives access to nuxtServerInit
inside of your file you can do this:
//NOTE this only works when mode is set to universal inside of your nuxt config
export const actions = {
async nuxtServerInit({ commit }) {
const data = await this.$axios.$get(`your-api`)
// you can do all of your logic here before commiting
commit('setAirports', data)
}
}
than all you have left to do is create a mutatation to fill the state with your data
export const mutations = {
setAirports(state, payload) {
state.airports.push(...payload)
},
}