Search code examples
vue.jsionic-frameworkasync-awaitvue-data

Vue Ionic template logic getting null data objects when data assigned inside async method


UPDATE Solution found, but I don't understand the reason. any explanation, please.

ORIGINAL QUESTION I have a Vue / Ionic project which is giving me hell.

I'm trying to use the following code, but problems starts when I try to assing a value to some data inside an async method.

It seems to assing correctly but some elements in the template can't find the content further than the level 0 of nesting, as shown in the images below. If I try to reach an object property, the object seems to be null when not null at all.

<template>
    <h6>{{proyectos}}</h6> <!--THIS WORKS OK-->
    <!-- <h6>{{proyectos[0]}}</h6> THIS DOESN'T -->
    <!-- <h6 v-if='proyectos[0]'>hola</h6> NEITHER THIS-->
    <div
        v-for='proyecto in proyectos'
        :key='proyecto.id'
    >
        <h3>{{proyecto.id}} - {{proyecto.nombre}}</h3>
    </div>
</template>

<script>
export default {
    data(){
        return{
            proyectos: null,
        }
    },

    methods: {  
        async misproyectosIniciar(){
            await this.$store.dispatch('actObtenerProyectos'); //REQUIRES AWAIT
        },

        obtenerProyectos(){
            return this.$store.getters.proyectos;
        },
    },

    async beforeMount(){
        await this.misproyectosIniciar();
        this.proyectos = this.obtenerProyectos();
        console.log('proyectos', this.proyectos);
        console.log('proyectos[0]', this.proyectos[0]);
    },
};
</script>

I removed all ionic components, since it always causes me problems.

If I just use the v-for, everything works fine.

image of it working fine

If I uncomment any of the two lines at the top of the code ({{}}, v-if), then errors show up.

image of it NOT working

I have no idea why this is happening, any clues, please?. NOTE: It does requires await since is a database query.


Solution

  • the object seems to be null when not null at all

    Thats not true. At the very begin, your property value is indeed null. Lets say your query takes about 1 sek to fetch the data, so only after 1 sek you assign an value to it, and then its not null anymore.

    So your value is for 1 sek, null in this example.

    Look, async / await does not execute code in sync.

    Imagine your database call takes about 1 second to retreive some data.

    While your code is fetching the data, vue tries to render the v-for but the value is null because in the background the data is being fetched.

    Also, always (well almost always) initialize arrays with [] not with undefined null or something other.

    [] works because of this reason:

    null didnt worked, because you basically tried to do this:

    null.forEach(() => {})

    You basically tried to loop over null, and if you know javascript you will know that this does not work.

    But if you initialize it with [] you actually can loop over, even if there is nothing in it

    [].forEach(() => {})