Alexandru Ana
Alexandru Ana

Reputation: 75

Nuxt: how to load data to store on app initialization

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?

Upvotes: 4

Views: 6680

Answers (2)

niels van hoof
niels van hoof

Reputation: 489

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)
  },
}

Upvotes: 0

Phillip
Phillip

Reputation: 6253

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

Upvotes: 1

Related Questions