Ioan Dimi
Ioan Dimi

Reputation: 209

Empty array after page's refreshing Vue.js and axios

I am new with the coding, with vue cli and my english are not so good ,so forgive me if i don't explain the issue well , but i will try because the community is my last option.

This is the store.js that i fetch the json from the server and suppose to pass the data to the child components.

store.js

import Vue from "vue";
import Vuex from "vuex";
import axios from "axios";
import VueAxios from "vue-axios";
import { library } from '@fortawesome/fontawesome-svg-core'
import { faCoffee } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'

library.add(faCoffee)

Vue.component('font-awesome-icon', FontAwesomeIcon)

Vue.use(Vuex);
Vue.use(VueAxios, axios);


export default new Vuex.Store({
  state: {
    beers: [],
    isLoaded: false
  },
  actions: {
    async loadCoins({ commit }) {
      axios
        .get("https://api.punkapi.com/v2/beers")
        .then(r => r.data)
        .then(beers => {
          commit("SET_BEERS", beers);
          commit("BEERS_LOADED", true);
        });
    }
  },
  mutations: {
    SET_BEERS(state, beers) {
      state.beers = beers;
    },
    BEERS_LOADED(state, isLoaded) {
      state.isLoaded = isLoaded;
    }
  },
});

This file is the home.vue component that i present my data and there is a router link which should be redirect me to the next component. The router link expect for the item's id

  <template>
  <div>
    <div
      v-for="(value,index) in  beers"
      :key="index"
    >
      <router-link :to="{ path: `/about/${value.id}`}">
        <img
          class="logo lazy img-responsive loaded"
          v-bind:src="value.image_url"
        />
        <div>{{value.name}}</div>
        <div> {{value.tagline}}</div>
      </router-link>
    </div>
  </div>
</template>
    <script>
const _ = require("lodash");
import { mapState } from "vuex";
import Carousel from "@/components/carousel.vue";

export default {
  name: "home",
  components: {
    Carousel
  },
  data() {
    return {
      // filteredBeers: []
    };
  },
  mounted() {
    this.$store.dispatch("loadCoins");
    // this.test();
  },
  created() {},
  computed: {
    ...mapState(["beers", "isLoaded"]),
    consoleMyLog() {
      return this.isLoaded;
    }
  }
};
</script>

This file is the page with the details for each item. **And the problem is here, when i refresh the page i get an empty list **

I think that the approach is wrong but i don't have any idea why that happened and how to fix, might i don't use the framework well.

So any recommendation is welcome.

Thanks in advance

<template>
     <div>
          <img
            class=" logo" 
            v-bind:src="selectedArticle[0].image_url"
          />
          <h2 class="beer-title">
            {{selectedArticle[0].name}}
          </h2>
          <h3 class="beer-style">
            {{selectedArticle[0].contributed_by}}
          </h3>
     </div>
</template>


<script >
const _ = require("lodash");
import { mapState } from "vuex";

import Carousel from '@/components/carousel.vue'
export default {
  name: "about",
  props: {
    //  proId: this.$route.params.Pid,
  },
  components: {
    Carousel,
 
 },
  data() {
    return {
      

    };
  },
  computed: {
    // return the beers obj filter it by id and match it with route_id
    selectedArticle() {
      return this.$store.state.beers.filter(
        beer => beer.id == this.$route.params.id
      );
    }
  },
  mounted() {

   
  },
  }
</script>

Upvotes: 0

Views: 1786

Answers (1)

Daniel
Daniel

Reputation: 35704

I can't tell for certain, but it does look like home and about are two separate routes.

so the interaction is

  • your home component loads the data
  • user navigates to about and the page renders OK
  • user refreshes, and now it's not working

If that's the case, the reason for getting the error is clear. The home component loads the data in the mounted handler. When you refresh, and you 're now in the about component, the action to load the data is no longer performed.

To fix this, there are several ways varying in robustness and ease and scalability, but based only on the code I've seen, I'd say the fastest way to fix it is to update the mounted handler in about.vue

mounted() {
  if (this.$store.state.beers.length === 0) this.$store.dispatch("loadCoins");
},

Upvotes: 2

Related Questions