3

apologies for the simple question, I'm really new to Vue/Nuxt/Vuex.

I am currently having a vuex store, I wish to be able to populate the list with an API call at the beginning (so that I would be able to access it on all pages of my app directly from the store vs instantiating it within a component).

store.js

export const state = () => ({
    list: [],
})

export const mutations = {
    set(state, testArray) {
        state.list = testArray
    }
}

export const getters = {
    getArray: state => {
        return state.list
    },
}

I essentially want to pre-populate state.list so that my components can call the data directly from vuex store. This would look something like that

db.collection("test").doc("test").get().then(doc=> {
    let data = doc.data();
    let array = data.array; // get array from API call
    setListAsArray(); // put the array result into the list
});

I am looking for where to put this code (I assume inside store.js) and how to go about chaining this with the export. Thanks a lot in advance and sorry if it's a simple question.

(Edit) Context: So why I am looking for this solution was because I used to commit the data (from the API call) to the store inside one of my Vue components - index.vue from my main page. This means that my data was initialized on this component, and if i go straight to another route, my data will not be available there.

This means: http://localhost:3000/ will have the data, if I routed to http://localhost:3000/test it will also have the data, BUT if i directly went straight to http://localhost:3000/test from a new window it will NOT have the data.

EDIT2:

Tried the suggestion with nuxtServerInit

Updated store.js

export const state = () => ({
    list: [],
})

export const mutations = {
    set(state, dealArray) {
        state.list = dealArray
    }
}

export const getters = {
    allDeals: state => {
        return state.list
    },
}

export const actions = {
    async nuxtServerInit({ commit }, { req }) {
        // fetch your backend     
        const db = require("~/plugins/firebase.js").db;
        let doc = await db.collection("test").doc("test").get();
        let data = doc.data();
        console.log("deals_array: ", data.deals_array); // nothing logged
        commit('set', data.deals_array);       // doesn't work
        commit('deals/set', data.deals_array); // doesn't work
    }
}

Tried actions with nuxtServerInit, but when logging store in another component it is an empty array. I tried to log the store in another component (while trying to access it), I got the following:

store.state:  {                                                                                                                                     
  deals: {
    list: []
  }
}
Xam
  • 31
  • 4
  • You can hit the api in your layout file (usually index.vue) file. Just hit the api and on success commit the result and store the result in the vuex. – Helper Jul 10 '20 at 11:06
  • Hey, if i use the api on my main `index.vue` file, the problem is that i wouldn't be able to access the store on other pages directly (because it only initializes there) – Xam Jul 10 '20 at 11:22
  • I didn't understand this: "i wouldn't be able to access the store on other pages directly". Can you please elaborate? Moreover, you can hit the API in the action part of the store as well. Just invoke the same in the index.vue file. – Helper Jul 10 '20 at 11:25
  • So what i previously had was the API in one of the components which committed to the store (my main page `index.vue`), but i couldn't access if i went straight to the routed page (because it hasn't be initialized from the main page). I'm trying to find a way to initialize the data array even before the components are built – Xam Jul 10 '20 at 11:35
  • Hey atul, I have added more explanation about my context above, hope it helps – Xam Jul 10 '20 at 11:38
  • Vuex doesn't works like this actually. That is the exact problem actually: "http://localhost:3000/test from a new window it will NOT have the data" which I was pointing to in your previous post. If the user refreshes it or directly opens the /test url you wont be able to get the values. – Helper Jul 10 '20 at 11:39
  • Well in that case, you could have done something like this: 1. Check if the desired value is present in the vuex. 2. If yes then retrieve the same. 3. If not, then hit the api and the populate the vuex. This can save you api hits if the user opens the /test page again. – Helper Jul 10 '20 at 11:41
  • I would be keen to find out how to go about with that approach. The suggested answers didn't seem to work for me. – Xam Jul 10 '20 at 12:15
  • Your suggestions seem to be loading the API call several times, I'm looking for the possibility of globally initiating the API data, then loading directly from the store from then on – Xam Jul 10 '20 at 12:19
  • yeah that is why I didn't suggested nuxtServerInit. You can proceed with what I said. – Helper Jul 12 '20 at 04:24

1 Answers1

2

I would suggest to either:

  1. calling the fetch method in the default.vue layout or any page
  2. use the nuxtServerInit action inside the store directly

  1. fetch method

You can use the fetch method either in the default.vue layout where it is called every time for each page that is using the layout. Or define the fetch method on separate pages if you want to load specific data for individual pages.

<script>
export default {
  data () {
    return {}
  },
  async fetch ({store}) {
    // fetch your backend 
    var list = await $axios.get("http://localhost:8000/list");

    store.commit("set", list);
  },
}
</script>

You can read more regarding the fetch method in the nuxtjs docs here

  1. use the nuxtServerInit action inside the store directly

In your store.js add a new action:

import axios from 'axios';

actions: {
  nuxtServerInit ({ commit }, { req }) {
     // fetch your backend     
     var list = await axios.get("http://localhost:8000/list");

      commit('set', list);
    }
  }
}

You can read more regarding the fetch method in the nuxtjs docs here

Hope this helps :)

dummker
  • 315
  • 1
  • 13
  • 1
    Hey thanks for the answer! sorry for another question but how do i place this inside `store.js`? Right now there are those 3 export functions as highlighted above. – Xam Jul 10 '20 at 11:44
  • @Xam, please refer this: https://nuxtjs.org/guide/vuex-store/#the-nuxtserverinit-action. Moreover, can you please let me know if your project mode is universal? – Helper Jul 10 '20 at 11:48
  • Hey there, I tried your 2nd suggestion but didn't seem to work... Updated the question with my observations... – Xam Jul 10 '20 at 12:16