Rendu basé sur une valeur récupérée de manière asynchrone

Production qui ne se comporte pas comme le développement

a marqué ce sujet comme résolu.

Bonsoir :)

Je bidouille avec Vue.js en ayant repris un vieux projet sous Nuxt 2. Le projet étant un peu trop conséquent pour être migré actuellement, je tente de me familiariser avec les concepts en espérant que cela ne pose pas de problème pour passer à une version plus récente du framework. En plus de cela, je constate des différences de comportement entre un lancement de débogage de l’application et un lancement "production". Ajouter encore que le principe des Promise avec async et await n’est probablement pas complètement maitrisé… me voici.

Dans le cas qui m’occupe, je dois notamment gérer des rôles afin d’afficher ou non une nouvelle option de navigation, en attaquant une pseudo-API pour récupérer lesdits rôles. J’ai déjà ce genre de fonctionnalité pour des éléments qui sont rendus "plus tard" basés sur d’autres données asynchrones, mais je bloque sur quelque chose qui doit être pris en compte plus tôt dans le déroulé, et qui ne se comporte pas comme je m’y attendrais.

Concrètement, j’ai le code suivant — un peu simplifié évidemment.

<template>
    <v-row v-if="list.length > 0 && canExport" data-etc >
         <a …>Exporter</a>
    </v-row>
</template>

<script>
new Vue({
    data: {
        list: [],
        roles: [],
    },
    methods: {
        canExport: function() {
            return roles.length > 0 && roles.some('EXPORT');
        }
        // une autre méthode très similaire sur un autre tableau aussi dans data
    },
    async created() {
        await this.$store.dispatch('getRoles').then((roles) => {
            this.roles = roles || [];
        });
        // un autre appel, différent du fait du paramètre de dispatch() et de la propriété
        // dans laquelle le retour est enregistré. C'est bien la même propriété que celle
        // mentionnée ligne 17. Permuter les appels ne change rien.
    }
});
</script>

En lançant mon application "en mode débogage", je n’ai aucun problème, tout roule. Si je lance npm run build et que je lance "en mode production", par contre…

L’application n’arrive pas à compléter son initialisation.

nuxt DOMException: Node.appendChild: Cannot add children to a Comment

J’ai tenté de jouer avec les différents événements disponibles de Nuxt, comme beforeMount(), mounted(), mais surtout fetch(), qui permet un rendu et une utilisation pratiquement correcte. Pratiquement, parce qu’il me faut passer à une autre page et revenir sur celle qui me préoccupe (c’est la page d’accueil) pour que, cette fois, le bouton d’export s’affiche avec le contenu de la liste. Parce que la requête à l’initialisation ne semble pas remplir roles si j’en crois les outils de débogage. Par contre, je ne comprends pas pourquoi partir et revenir sur la page hydrate la propriété.

Je suis conscient que le problème peut venir de plusieurs points, mais là, j’aurais besoin d’un œil externe pour me réorienter et m’expliquer pourquoi ça ne fonctionne pas avec ce que j’ai, un peu naïvement certes, copié pour adapter.

Merci d’avance  :)

+0 -0

Hello, je pense que rien ne dit à ton composant qu’il doit fait un re-render : tu définis sa propriété roles mais il ne va pas de lui-même se mettre à jour.

D’où le fait qu’au retour sur la page ton bouton apparaisse : il y un re-render car le composant est re-monté en mémoire depuis le cache (cette fois avec la donnée déjà pré-chargée depuis l’affichage précédent).

En cherchant rapidement je suis tombé sur ce topic StackOverflow qui propose différentes méthodes, mais comme j’ai pas pratiqué Vue depuis 7 ans ( :-° ) je peux pas trop t’aider à choisir la plus adaptée à ton cas

Alors j’avais dû mal comprendre, il me semblait que les propriétés mises dans data étaient rendues "réactives", donc un changement de valeur ferait recalculer là où la variable est utilisée. roles y étant, ça me semblait suffire. Bon, de toute manière, si j’en crois les outils de débogage, je n’arrive même pas à la remplir au premier accès à l’application, donc ce point viendra par après.

Par contre, je me dis maintenant qu’il pourrait y avoir une subtilité avec les tableaux. Mais je dirais aussi que j’écrase ledit tableau, je n’y ajoute pas d’éléments, donc ce n’est pas l’opération d’assignation en elle-même qui pose problème.

+0 -0

Ah oui, étant un tableau c’est plus compliqué de détecter les changements au remplacement plutôt qu’à la modification, le pointeur n’étant plus le même.

Ça pourrait effectivement être ça, j’ai des souvenirs de surprises du genre sur Angular, ça m’étonnerait pas que Vue soit pareil… ^^

Dans les deux cas il faudra probablement trouver un moyen de forcer un render (ou alors tenter de garder le même tableau, mais si ça demandera peut-être pas mal de calcul/complexité en plus)

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte