web-dev-qa-db-fra.com

Vue JS en attente de données avant le rendu

Je suis pile depuis quelques semaines dans un problème de rendu de données avec VueJS.

Je fais des appels axios (l'un dans l'autre). Mon problème est que les données sont rendues avant la fin des appels, donc la vue n'affiche rien.

J'ai vu des codes qui font des "appels d'attente" et des "appels asynchrones" mais rien ne semble résoudre mon problème.

Il y a aussi quelque chose de similaire ici Obtenir le composant pour attendre les données asynchrones avant le rend Mais ne fonctionne pas non plus

voici mon 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">
                                Paciente: 
                                {{ diagnose.details[0].name }}
                                </a><br>
                                <a href="#" class="m-widget2__link m-link">
                                Tratante: 

                                </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('/pacientes/request-json/agenda/validarAsistencia/eventos').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('cargando');
            this.events.forEach(event => {
                axios.get('/pacientes/request-json/agenda/validarAsistencia/eventos/' + event.id).then(res => {
                    event.details = res.data;
                    console.log(res.data);
                });
            });
            this.distributeEvents();
            console.log('montado');
        },    

        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...
        }

    }

}
5
Pablo Araya

La solution:

Merci les gars !

         loadData: function() {
            axios.get('/pacientes/request-json/agenda/validarAsistencia/eventos')
                .then(res => {
                    this.events = res.data;
                    this.getDelayColor() // sync operation; no need to be returned
                    this.getConcurrence();
                    vm.$nextTick(function () {
                        $('[data-toggle="m-tooltip"]').tooltip();
                    });
                    return this.getDetails(); // Return 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.distributeEvents();
                    console.log('end LoadData');
                })
                .catch(error => {
                    console.log('error');
                })
        },

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

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

            return Promise.all(promisedEvents)
        },
0
Pablo Araya