Vue JS ensures that it has all the necessary data before proceeding with the

I've been grappling with a VueJS data rendering issue for a few weeks now.

My approach involves making axios calls, some nested within others. The problem I'm facing is that the data renders before the calls have completed, resulting in an empty view.

I've looked into using "await" and asynchronous calls in my code, but nothing seems to be resolving the issue.

I also came across a similar question on Stack Overflow: Get component to wait for asynchronous data before rendering Unfortunately, even that solution doesn't seem to work for me.

Here is a snippet of my code:

<template>
     <div class="m-portlet m-portlet--full-height" m-portlet="true" id="m_portlet_validate_agenda">
    ...
    <div class="m-portlet__body">
        <div class="tab-content">
            <div class="tab-pane active" id="m_widget2_tab1_diagnose">
                <div class="m-widget2">
                    <div v-for="diagnose in diagnoses" v-if="diagnoses.length" :class="'m-widget2__item m-widget2__item--' + diagnose.delayColor[0]">
                        <div class="m-widget2__checkbox" >
                            <label class="m-checkbox m-checkbox--solid m-checkbox--single m-checkbox--brand">
                                <span class="m--bg-white" v-html="diagnose.concurrence"></span>
                            </label>
                        </div>
                        <div class="m-widget2__agenda col-2">
                            {{ diagnose.started_at | moment("HH:mm A") }}
                        </div>
                        <div class="m-widget2__desc" v-if="!isFetching">
                            <div>
                                <span class="m-widget2__text">

                                </span><br>
                                <span class="m-widget2__user-name">
                                    <a href="#" class="m-widget2__link m-link">
                                    Patient: 
                                    {{ diagnose.details[0].name }}
                                    </a><br>
                                    <a href="#" class="m-widget2__link m-link">
                                    Attending Physician: 

                                    </a>
                                </span>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
         </div>
       </div>
     </div>
    </template>

    <script>
    export default {

        data() {
            return {
                events: [],
                diagnoses: [],
                urgencies: [],
                treatments: [],
                isFetching: true
            }
        },

        mounted() {
            this.loadData();
        },

        methods: {

            loadData: async function() {
                await axios.get('/patients/request-json/agenda/validateAttendance/events').then(res => {
                    this.events = res.data;
                    this.diagnoses = [];
                    this.urgencies = [];
                    this.treatments = [];
                    this.getDetails();
                    this.getDelayColor();
                    this.getConcurrence();
                    vm.$nextTick(function () {
                        $('[data-toggle="m-tooltip"]').tooltip();
                    });
                    console.log('end LoadData');
                });
            },

            getDetails: function() {
                console.log('loading');
                this.events.forEach(event => {
                    axios.get('/patients/request-json/agenda/validateAttendance/events/' + event.id).then(res => {
                        event.details = res.data;
                        console.log(res.data);
                    });
                });
                this.distributeEvents();
                console.log('mounted');
            },    

            distributeEvents: function() {
                this.events.forEach(event => {
                    if ( event.event.event_type == "diagnosis" )
                    {
                        this.diagnoses.push(event);
                    }
                    else if ( event.event.event_type == "urgency" )
                    {
                        this.urgencies.push(event);
                    }    
                    else if ( event.event.event_type == "treatment" )
                    {
                        this.treatments.push(event);
                    }
                });
                this.isFetching = false;
            },

            getDelayColor: function() {
                this.events.forEach(event => {
                    do something...
                });
            },

            getConcurrence: function() {
                this.events.forEach(event => {                    
                    do something...
                });
            },

            diffMinutes: function(started_at) {
                do something...
            }

        }

    }

Answer №1

To ensure that the component is not rendered until the data has been retrieved, consider taking the following steps:

  1. Include an "isFetching" property in the data and initialize it as "true"

  2. In the fetch callback, update isFetching to be "false"

3. Add v-if="!isFetching" to the wrapper of the component

Answer №2

It seems like the issue lies in how you are handling Promises, causing them to remain unresolved. One approach is to utilize async, await, or stick with using plain Promise Objects:

Looking at the getDetails() function, there is a loop where an axios request is made for each item in the array. To address this, you should collect all the Promises generated by these requests into an array and then use Promise.all to handle them together.

    getDetails: function() {
        let url = '/pacientes/request-json/agenda/validarAsistencia/eventos/';
        console.log('loading');
        let promisedEvents = [];

        this.events.forEach(event => {
            promisedEvents.push(axios.get(url + event.id))
        });

        return Promise.all(promisedEvents)
    },

Following that, consider structuring your code like this:

    loadData: function() {
        axios.get('/pacientes/request-json/agenda/validarAsistencia/eventos')
            .then(res => {
                this.events = res.data;
                this.getDelayColor() // synchronous operation; no need to return
                return this.getDetails(); // Return the promise(s) here
            })
            .then((res) => {
                // perform actions based on the responses of your Promises
            })
            .then(anotherPromise) // You can also return a promise like this 
            .catch(handleError) // It's crucial to handle errors properly!
        });
    },

This may not be the only solution, but it provides a way to resolve the issues in your code. It's essential to familiarize yourself with how Promises work in JavaScript.

Answer №3

The Resolution:

Thank you all for your help!

         handleDataRetrieval: function() {
            axios.get('/patients/request-json/schedule/validateAttendance/events')
                .then(res => {
                    this.events = res.data;
                    this.getColorDelay(); // Performs synchronously; does not need to be returned
                    this.checkConcurrence();
                    vm.$nextTick(function () {
                        $('[data-toggle="m-tooltip"]').tooltip();
                    });
                    return this.obtainDetails(); // Returns the promise(s)
                })
                .then((res) => {
                    console.log(res.length);
                    for (var i = 0; i < res.length; i++) {
                        this.events[i].details = res[i].data;
                    }
                    this.arrangeEvents();
                    console.log('Finished Data Retrieval');
                })
                .catch(error => {
                    console.log('error');
                })
        },

        obtainDetails: function() {
            let url = '/patients/request-json/schedule/validateAttendance/events/';
            let promisedEvents = [];

            this.events.forEach(event => {
                promisedEvents.push(axios.get(url + event.id))
            });

            return Promise.all(promisedEvents)
        },

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

Importing modules from another module in Node.js

I'm currently working on a nodejs app that consists of two files, index.js and ping.js. The main functionality is in index.js which handles routing and other tasks, while ping.js utilizes phantomJS. In my index.js file, I have the following line of co ...

Exploring the quirky characters in the PHP mail() function

Currently using the php mail function, it's somewhat effective, although not my preferred method. However, it seems I must make do for now. The issue at hand is that special European characters are showing up strangely in the email. I attempted to se ...

Utilizing Mantine dropzone in conjunction with React Hook Form within a Javascript environment

Can Mantine dropzone be used with React hook form in JavaScript? I am currently working on a modal Upload using Tailwind components like this import { useForm } from 'react-hook-form'; import { Group, Text, useMantineTheme } from '@mantine/c ...

What is the process for accurately showcasing the attributes of a table when there is an additional intermediary table involved?

I am a beginner in programming and facing an issue with displaying the properties of a table. There is an intermediate table involved and I have set up the route like this in my nodejs: router.get('/getById/:id', (req, res) => { db.annonce ...

Please provide me with the coordinates (latitude and longitude) for that address

I am looking to integrate the Google geocoder into my website. I want to be able to input any location address and receive the latitude and longitude coordinates for that location. Are there any helpful tutorials available? For reference, I found a simila ...

Tips for sending a reference to a JavaScript function

While constructing a table with DataTables and utilizing AJAX as its data source, I am encountering an issue with passing a function into the AJAX parameters. The $.post() function from regular JQuery seems to always send the value of my variable when the ...

Displaying an STL file at the center of the screen using Three.js positioning

I need assistance with positioning a rendered STL file from Thingiverse in the center of the screen using Three.js and the THREE.STLLoader(). Currently, I have to adjust the rotation properties based on touch coordinates to get the object where I want it. ...

I am looking to dynamically insert a text field into an HTML form using jQuery or JavaScript when a specific button is clicked

This is my code snippet: <div class="rButtons"> <input type="radio" name="numbers" value="10" />10 <input type="radio" name="numbers" value="20" />20 <input type="radio" name="numbers" value="other" />other </div> ...

Invalid content detected in React child element - specifically, a [object Promise] was found. This issue has been identified in next js

Why am I encountering an error when I convert my page into an async function? Everything runs smoothly when it's not an async function. The only change is that it returns a pending object, which is not the desired outcome. This is how data is being f ...

When attempting to send a POST request to /api/users/login, the system returned an error stating that "

Is there a way to make a post request to the mLab Database in order to determine if a user account already exists? The server's response states that the User is not defined. Can you please review my code? // @route post api/user/login# router.post(& ...

Using React to retrieve an object from a helper method through a GET request

I am in the process of turning a frequently used function in my application into a helper method that can be imported wherever it is needed. However, I am facing an issue where I am not getting a response from the function when calling it. I need to figure ...

Adding content to a text field and then moving to the next line

I am looking to add a string to a text area, followed by a new line. After conducting some research, here are the methods I have attempted so far but without success: function appendString(str){ document.getElementById('output').value += st ...

SignalR gets stuck on the 'Initiating start request' screen, halting all progress

SignalR has been causing some strange behavior for me lately. After doing some refactoring, I started experiencing connectivity issues. It seems like my code was just lucky to work before because it didn't follow the recommended practices. For example ...

Utilize moment.js to convert an epoch date into a designated time zone

I've spent countless hours searching for a resolution to the issue with moment.js and its inability to accurately display the correct date for a given local time zone. Let me explain my predicament: The flight API I'm utilizing provides me w ...

Anticipate commitments during onbeforeunload

Is there a way to trigger a $http.get request when the page is closed? I encountered an issue where promises cannot be resolved because once the final method returns, the page is destroyed. The challenge lies in the fact that onbeforeunload does not wait ...

Choose the item to automatically reposition itself below once it has been opened

issue : The current behavior is that when the "other" option is selected, the input field appears. However, if I click on the select again, it covers up the input field. desired outcome : Ideally, I want the input field to show up when the "other" option ...

Only one bootstrap collapse is visible at a time

Currently, I am using Bootstrap's collapse feature that displays content when clicking on a specific button. However, the issue I am facing is that multiple collapses can be open at the same time. I want to ensure that only one collapse is visible whi ...

Use jQuery to display the first 5 rows of a table

I recently posted a query on show hide jquery table rows for imported xml data regarding how to toggle visibility of specific table rows using jQuery. Now, I am seeking advice on how to make the first 5 elements always visible within the same context. Belo ...

Adding 2-dimensional text to a specified location with the help of three.js

let startPosition = new THREE.Vector3(-5,0,0); let targetPosition = new THREE.Vector3(-5,2,0); let directionVector = new THREE.Vector3().sub(targetPos,startPosition); let arrowHelper = newTHREE.ArrowHelper(directionVector.clone().normalize(),startPosition, ...

What could be causing the Access-Control-Allow-Origin error to appear when attempting to access a page using ajax?

As I attempt to utilize Ajax to retrieve data from my website using a script that should be able to execute from any location, the Ajax code within my script is structured like this: var ajax = new XMLHttpRequest(); ajax.open('GET', 'http:/ ...