How can you make a button in Vue only visible after all API calls have successfully retrieved the data?

Is there a way to make the report button visible only after all the data has been loaded from the latest click of the budget button? Currently, when the budget button is clicked, it retrieves budgets and displays them in a Vue grid using Kendo Grid. To speed up data loading, the grid initially loads with some data before making additional API calls for two more columns of data. These subsequent API calls are processed 10 at a time in a loop due to potential delays. What's the simplest approach to show the button once all the data has finished loading?

I've shared my current method for retrieving budgets and the computed property that determines when the report button should appear. One issue I'm encountering is that even if I reset the estimateAmounts object array at the start of the getBudgets method, existing loops may still be running from previous calls and affecting the comparison with the data object in my computation. Any suggestions on how best to address this challenge would be greatly appreciated. Feel free to reach out if you need more information.

    data() {
                return {
                    budgets: [],
                    estimateAmounts: {},
                }
           },
methods: {
    async getBudgets() {

                this.isLoading = true;
                this.budgets = []
                this.estimateAmounts = {}
                const data = await api.budget.getBudgetReport({ 
                  accountIds: this.accountIds.map(a => a.accountId),
                  salesRepIds: this.selectedSalesReps.map(sr => sr.userId),
                  startDate: this.startDate, 
                  endDate: this.endDate 
                })
                this.budgets = data.map(d => { return { ...d, startDate: new Date(d.startDate) } })
                this.isLoading = false;

                // group calculations in 10's to run concurrently and return results faster
                let idSets = chunk(data.map(d => d.budgetId), 10)
                for (const ids of idSets)
                    api.budget.calculateTotalsForBudgets(ids, this.user.userId)
                        .then(res => this.estimateAmounts = { ...this.estimateAmounts, ...res })
            },
    },

    computed: {
        setButtons() {
                        return Object.keys(this.estimateAmounts).length == this.budgets.length && this.budgets.length > 0
                    },
    }

Answer №1

If my understanding is correct, you simply wish to wait for all parallel API calls to finish before displaying a button in the template. This can be accomplished using await Promise.all without the need for any computed property. Here's an example:

this.displayButton = true;
await Promise.all(
    idSets.map(async (ids) => {
        await api.budget.calculateTotalsForBudgets(ids, this.user.userId);
    })
);
this.displayButton = false;

I introduced a new displayButton state as an illustration, but you could possibly utilize your existing isLoading state -- just place it below.

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

Tips for deactivating a single edit button

Is there a way to make it so that when I click on a checkbox, only that specific todo's edit button is disabled? Currently, clicking on a checkbox disables all edit buttons in the todo list. Any suggestions? class App extends Component { state ...

The V-model is failing to bind properly as anticipated

One feature of my application involves a table that displays a list of products. Each product row in the table has an input field where users can enter the quantity they want to purchase. The total cost for each product is dynamically calculated by multipl ...

What is the best way to initiate a TouchEvent in a qunit test being run by grunt using only vanilla JavaScript?

I have implemented callbacks for different touch events that require testing. For example, the 'touchstart' event utilizes touch coordinates to configure a class member: NavigationUI.prototype.touchStart = function(evt) { this.interacting = ...

What are some methods to boost productivity during web scraping?

Currently, I have a node script dedicated to scraping information from various websites. As I aim to optimize the efficiency of this script, I am faced with the challenge that Node.js operates on a single-threaded runtime by default. However, behind the sc ...

A customizable and adaptable Tetris-inspired CSS design perfect for any screen size

If we imagine having a block like this: <div class="block"></div> There are different sizes of the block: <div class="block b1x1"></div> <div class="block b2x1"></div> <div class="block b1x2"></div> For i ...

Enhancing Donut Chart with d3.js

After working for several hours, I'm having trouble getting my d3.js donut graph to update with new data. Here's my HTML: <body> <div id="pie"></div> <script src="pie.js"></script> </body> And he ...

Exploring data-toggle elements using jQuery

I am faced with the challenge of dynamically constructing a form using jQuery. The form includes a checkbox list of items that I am creating in the following manner: function initializeForm() { var html = ''; var items = GetItems(); for ( ...

Dispatch an angular POST Request

I am facing an issue where Angular is sending a GET request instead of a POST request when I want to send a post request. The code for my Angular request is as follows: $http({ method: 'POST', url: pages_url, params: { ...

Is there a way to create an input field that accepts only numbers and behaves like a password field simultaneously?

I am attempting to develop an input field for entering a PIN. I would like the PIN to be masked on mobile devices, similar to how passwords are obscured in password input fields. I came across a suggestion on stackoverflow regarding this, but unfortunately ...

CKEditor5: Unable to access the 'pluginName' property because it is undefined

I am facing a challenge in creating a custom image plugin for CKEditor that can seamlessly integrate with my own image upload system. While trying to set up this plugin, I encountered some difficulties. Oddly enough, the "out-of-the-box" plugins work perfe ...

Issue with Material-UI Nested Checkbox causing parent DOM to not update upon selection changes

Currently, I am integrating a nested checkbox feature from a working example into my application. The functionality of the checkboxes covers seven different scenarios: - Scenario - No children, no parent selected - Select the parent -> select both pa ...

What is the best way to indicate a particular element within a subdocument array has been altered in mongoose?

I have a specific structure in my Mongoose schema, shown as follows: let ChildSchema = new Schema({ name:String }); ChildSchema.pre('save', function(next){ if(this.isNew) /*this part works correctly upon creation*/; if(this.isModifi ...

Node and Express Fundamentals: Delivering Static Resources

const express = require('express'); const app = express(); app.use(express.static('public')); I've been attempting to complete the "Basic Node and Express: Serve Static Assets" challenge on freecodecamp, but it keeps showing as " ...

Retrieve checkbox selected value using pug and node.js

How can I retrieve the value of a checked checkbox in order to redirect to (href="/player/edit/:id") or (href="/player/delete/: id"), and obtain the player id for editing or deleting? I have omitted other code details such as app.js which includes the ser ...

Updating the route in Express.js/Node.js to redirect form submission from `/page` to `/page/<input>`.Is this fine for you

How can I redirect a user from /page to /page/:nickname in Express after they enter a nickname and click submit? This is my code: // app.js app.get("/page", (request, response) => { response.render("page"); }); app.get("/page/:nickname", (reques ...

Enable Class exclusively on upward scrolling on the browser

Is there a way to dynamically change the class of an element only when the user scrolls the browser page upwards? Issue Filide>> JavaScript $(window).scroll(function() { var scroll = $(window).scrollTop(); if (scroll <= 100) { $( ...

Display HTML content generated by JavaScript in the page source

Can the HTML elements I've added through JavaScript and jQuery codes be displayed in the page source (ctrl+U)? ...

The problem with 500 localStorage not being defined in Nuxt.js is causing

Issue with [nuxt] [request error]: [unhandled] [500] Error - localStorage is not defined ۱۴:۴۲:۵۶ at isAuthenticated (C:\Users\Lenovo\Desktop\CR ...

Having trouble accessing the ng-model within ng-repeat in the controller of an AngularJS component

One approach I am considering is to use ng-model="model.ind[$index]" in order to keep track of the active tag. This way, when I click on a tag (specifically the 'a' tag), both the parentIndex and $index will be passed to my controller. Subsequent ...

Only include unique objects in the array based on a common property

I am currently working with the following array: [ {name: "Mike", code: "ABC123"}, {name: "Sarah", code: "DEF456"}, {name: "John", code: "GHI789"}, {name: "Jane", code: "JKL01 ...