1

I'm using the async fetch hook to render the component in SSR and making the API call inside the same. But on the live server, it is actually loading one more time on the client-side and making one more call to API and as API isn't exposed during client-side so data just washes away and the array object gets again set to empty.

 data() {
    return {
      errored: false,
      randomData: [],
    };
  },
 async fetch() {
    await this.$axios
      .get(this.routeUrl)
      .then((res) => {
        if (res.data.length == 0 || res.status != 200) this.errored = true;
        this.randomData = res.data;
      })
      .catch((err) => {
        console.log(err);
      });
  },
  fetchOnServer: true,

I want to persist this randomData variable, so there shouldn't be another call on the client-side to populate the same.

Nik
  • 352
  • 1
  • 11
  • So, you're using `ssr: true` and `target: 'server'`, right? Also, what is your end goal? Not having the request on the client side, only on the server? Because, the default behavior of an universal app, is to hydrate the content once you're on the client-side, hence triggering any hook a second time. Something [like this](https://stackoverflow.com/a/68431975/8816585)? – kissu Apr 27 '22 at 10:51
  • @kissu SSR is true and the target is set to server. My main goal is that the component doesn't create another request to API when on the client. It should be using the randomData variable that is populated on the server. But that randomData variable is [ ] just after a blink on the client. – Nik Apr 27 '22 at 11:08
  • Yeah, because you reset the value with `randomData: []` on your client-side. If you want to get some data on the server and pass it directly to your client, you could use [nuxtServerInit Vuex action](https://nuxtjs.org/docs/directory-structure/store#the-nuxtserverinit-action). More details in [the lifecycle](https://nuxtjs.org/docs/concepts/nuxt-lifecycle#nuxt-lifecycle). – kissu Apr 27 '22 at 11:12
  • @kissu So, this is the only way or there is more methods to persist the variable? – Nik Apr 27 '22 at 12:39
  • There are not a lot of ways to persist data across the server and client side and in this case, it's probably the best approach. What's wrong with that? – kissu Apr 27 '22 at 12:53
  • @kissu Thanks! I'll do it the way you suggested. – Nik Apr 27 '22 at 12:55
  • Have you considered the `asyncData` option? https://nuxtjs.org/docs/features/data-fetching/ If your component is a page component (ie: component in pages directory), you can fetch the data server-side before the component loads. – agm1984 Apr 27 '22 at 17:33
  • @agm1984 this doesn't fix the issue tho, `randomData` will still be cleared on initial hydration. – kissu Apr 27 '22 at 17:37
  • @kissu I needed clarification. So, maybe I'm using async fetch or asyncData, both are supposed to make another API call on the client-side during hydration? – Nik Apr 28 '22 at 11:21
  • Yes, they are called both on the server and client side as you can see here: https://nuxtjs.org/docs/concepts/nuxt-lifecycle/#nuxt-lifecycle – kissu Apr 28 '22 at 12:04
  • @kissu Thanks! Solved the issue. Answering my own question now. – Nik Apr 28 '22 at 14:29

2 Answers2

1

If you want to pass some data from the server-side into the client-side, you could use the nuxtServerInit Vuex action

/store/index.js

actions: {
  nuxtServerInit ({ commit }, { req }) {
    if (req.session.user) {
      commit('user', req.session.user)
    }
  }
}
kissu
  • 40,416
  • 14
  • 65
  • 133
1

So, the issue was that, as I was Docker and the API was only exposed to the server-side and not the client-side. For a blink, the content was available and then just all gone. Because the async fetch and asyncData hooks are called on the server and as well as on the client-side. I solved it using the Vuex store. Now I started storing the data fetched on the server in store and using the same on the client-side. Here is how I implemented that:

// store/index.js

export const state = () => ({
  randomData: [],
});
export const mutations = {
  SET_RANDOMDATA: (state, payload) => {
    state.randomData = payload;
  },
};
// Inside the component

// Fetch the data from API on server-side
async fetch() {
    if (process.server) {
      await this.$axios
        .get(this.routeUrl)
        .then((res) => {
          this.$store.commit("SET_RANDOMDATA", res.data);
        })
        .catch((err) => {
          console.log(err);
        });
    }
  },
computed: {
    ...mapState(["randomData"]),
},
fetchOnServer: true,
Nik
  • 352
  • 1
  • 11