Prevent the Vue page from loading until the data has been fetched successfully

I'm in the process of finding a way to prevent my page from loading until my fetch task is completed. I'm facing some issues that need to be addressed:

  • I have to re-fetch the data each time because I can't reuse the same data. (Changing views after it's loaded works, but reloading a route causes problems)
  • Anchor links are not functioning properly. For instance, if I have an anchor link #about located below some featured items, the #about section will be shifted lower because the featured items have just finished loading. It's challenging to implement a skeleton loading system as the number of items is dynamic.

Here is the current code I'm working on:

  data() {
    return {
      collections: [],
      items: []
    }
  },
  methods: {
    async fetchCollections() {
      const res = await fetch('http://localhost:4000/collections')
      return await res.json()
    },
    async fetchItems() {
      const res = await fetch('http://localhost:4000/items')
      return await res.json()
    }
  },
  async created() {
    this.collections = await this.fetchCollections()
    this.items = await this.fetchItems()
  }

I acknowledge that this approach may not be considered best practice and I might be making mistakes. Please offer constructive feedback rather than criticism, as I'm new to Vue and still improving my skills with JavaScript.

In summary

The desired outcome is for the page to complete loading only once the backend data has been retrieved.

Currently, the content pops up after a brief delay following the initial site load, which is not the intended behavior.

Answer №1

If you need to fetch data for your route, the recommended approach is to use Vue-router's Navigation guards. Check out the documentation for more information.
Below is some sample code that you can utilize:

async function fetchData() {
  const resCol = await fetch('http://localhost:4000/collections');
  const resColJson = await resCol.json();
  const resItems = await fetch('http://localhost:4000/items');
  const resItemsJson = await resItems.json();
  return { resColJson, resItemsJson };
}
export default {
  data() {
    return {
      collections: [],
      items: []
    }
  },
  beforeRouteEnter(to, from, next) {
    fetchData().then(({ resColJson, resItemsJson } ) => {
      next((vm) => {
        vm.collections = resColJson;
        vm.items = resItemsJson;
      });
    });
  },
  beforeRouteUpdate() {
    fetchData().then(({ resColJson, resItemsJson } ) => {
      this.collections = resColJson;
      this.items = resItemsJson;
    });
  },
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Proper method for verifying line-clamp in a Vue component

I came across a question that aligns perfectly with my current task - determining if text is truncated or not. The query can be found here: How can I check whether line-clamp is enabled?. It seems like my approach may not be accurate, so any guidance on ho ...

What is the best way to retrieve data in Vue from Node.js?

app.js router.get('/', (req, res) => { var cart = req.cookies.cart; res.sendFile(path.join(__dirname,'../../src/components/cart.html'),cart); }) shoppingCart.html <body> <div id="shop" class="container mt-3"&g ...

Having trouble importing the Renderer2 component in Angular

Trying to include Renderer2 with the following import: import { Renderer2 } from '@angular/core'; Encountering an error: "Module 'project/node_modules/@angular/core/index' does not have an exported member 'Renderer2'. Puzz ...

The method mockImplementation cannot be found on the busboyConstructor object

Despite extensive research, I have yet to find a solution to my problem. Whenever I attempt to mock busboy in my project using jest, I keep encountering an error stating that mockImplementation (and mockRestore) is not a function. import * as Busboy from ...

Implementing MouseEvents in Typescript React without having to pass them down to child elements

Is it possible to use Mouse Events on a whole React Element without having to pass it to a child element? I have been passing my handleEvent function to several functional components and now I want to know if it can be done without causing a TypeScript err ...

Tips for incorporating multiple inputs within a foreach loop

My challenge involves dealing with two input fields that allow users to add multiple records in a single form submission. I am currently using a foreach loop to iterate through one of the inputs and retrieve the value, but now I need a way to loop through ...

Encountering issues with Vue build on Heroku while implementing Lerna

Currently attempting to set up a Lerna monorepo on Heroku with an Express backend and Vue frontend. The components are stored within /packages/server and /packages/frontend respectively. The goal is to compile the Vue frontend during deployment and serve i ...

Modify the size value dialog during runtime

I am attempting to create a property or method that can change the size of my container dialog built using Vuetify. Initially, I need it to look like this: <v-flex xs12 md10> I believe that by creating a variable property, I can dynamically change ...

Angular location services

I'm experiencing some difficulties with the geolocation feature. It works fine when the user clicks allow, but there's an issue when using If else. If the user clicks deny, it doesn't insert into the else block. You can check out this DEMO f ...

Property undefined with all alert points filled

According to the console, I am facing an issue while trying to route to the dashboard after logging in because the surname property is undefined. However, when I check my alerts, I can see that it is filled correctly at all times. login(surName: string, pa ...

What could be causing the error message (No overload matches this call) to pop up when attempting to subscribe to .valueChanges() in order to retrieve data from Firestore?

Currently, I am developing an Angular application that utilizes Firebase Firestore database through the angularfire2 library. However, I am encountering a challenge. I must admit that my background is more in Java than TypeScript, so there might be some g ...

Guide on how to specify the return type for useMutation in the 'react-query' library

Here is the code snippet provided: const setFriendCode = (data: Params) => api({ data }) const [mutateSetFriendCode, state] = useMutation<Response, Params>( setFriendCode ) An issue arises with the type of parameters in the code. The compiler ...

Storing JSON data using Vuex

As I am delving into the world of Vuex store used with vue.js, I find myself wanting to implement it in a specific scenario. 1. Is STATE referring to any data, whether static or dynamic, that is provided by the server or stored in a JSON format? TEMPLATE ...

Solving the CORS problem between Vue.js and Flask: Troubleshooting XMLHttpRequest Blockade

Description: Currently working on developing a web application utilizing Vue.js for the frontend and Flask for the backend. The initial phase involves creating a simple login page, but encountering CORS (Cross-Origin Resource Sharing) issues when making r ...

The function 'transformArticles' is not recognized as a property of the object 'Article'

I'm encountering an issue with Typescript that I need help understanding. In my code, I have a route where I am importing a class called Article like this: import { Request, Response } from "express"; const appRoot = require("app-root-path"); import ...

Can Vue 3 Teleport only function to transport elements outside of the Vue environment?

Vue 3 introduces the Teleport feature, replacing the portal-vue plugin in Vue 2. However, I encountered an issue where it seems impossible to teleport a component to a place controlled by Vue within the app itself. It only seemed to work when porting compo ...

Passing all emitted events from Vue 3 child component to its parent - A complete guide

My Vue components are structured as follows: <TopParent> <!-- Listening for events from EventProducer here --> <Child_1> <Child_2> <Child_3> ... <Child_N> <EventProducer /> &l ...

Using Vue router to dynamically define the query key when calling router.push()

Hello, I am relatively new to using Vue and have been working on a project that involves making GET requests based on the current URL. In one of my functions, I am trying to dynamically set the value of filterType in the query key within the router.push() ...

Retrieve the total number of hours within a designated time frame that falls within a different time frame

Having a difficult time with this, let me present you with a scenario: A waiter at a restaurant earns $15/hour, but between 9:00 PM and 2:30 AM, he gets paid an additional $3/hour. I have the 'start' and 'end' of the shift as Date obje ...

The addition operator cannot be used with the Number type and the value of 1

Encountering an issue where the operator '+' cannot be applied to types 'Number' and '1' buildQuerySpec() { return { PageSize: this.paging.PageCount, CurrentPage: this.paging.PageIndex + 1, MaxSize: '' ...