3

I have this rather simple Vue component (stripped of unnecessary parts):

Vue.component('equipment-tree', {
    data(){
        return {
            tree: [],
    }
},
template: `
    <template>
        <div id="equipment_tree"></div>
    </template>`,
mounted: function(){
    this.getTreeView()
    console.log('4. TREE LOADED AND VISIBLE');;
},
methods: {
    setUpTree(){
        $("#equipment_tree").jstree("destroy");
        $('#equipment_tree').jstree({ 
            core : {
                data : this.tree,
                multiple: false,
                themes: { 
                    dots: true
                }
            },
        });
        console.log("2. TREE SET UP")
    },
    getTreeView(){
        fetch("myurl /*just a URL */", 
            {
                method: 'GET',
            })
            .then((response) => response.json())
            .then((data) => {
                console.log('1. GOT DATA');
                this.tree = JSON.parse(data.tree);
                this.setUpTree();
                console.log('3. SET UP COMPLETE');
            })
        }
    }
})  

On mount, I call the method getTreeView() that gets the data from the database, saves it in the variable tree, and then calls setUpTree() which creates a tree using the jstree library. When I run it in the log I see

4. TREE LOADED AND VISIBLE
1. GOT DATA
2. TREE SET UP
3. SET UP COMPLETE

that is, the flow continues after the call to getTreeView(). Now, what if I want to wait until getTreeView() finishes so that the log 4. TREE LOADED AND VISIBLE gets actually printed last?

I tried with async/await as follows: I changed

mounted: function(){
        this.getTreeView()
        console.log('4. TREE LOADED AND VISIBLE');;
    }

into

mounted: async function(){
        await Promise.resolve(this.getTreeView());
        console.log('4. TREE LOADED AND VISIBLE');
    }

but I got the same result as before. Same if following the answers to this question. How can I wait for the method getTreeView() to finish?

Please, note that this is a reduced example because I want to understand how it works, not just because the order of log matters.

2
  • Is there any reason not to make gettreeview asynchronous so you can await it directly? Commented Sep 26, 2021 at 21:54
  • 2
    This is not a vue thing this is how async code works. Your function getTreeView is dealing with promises, it executes right away but the side effects it results in happen when the promise is resolved. Commented Sep 26, 2021 at 22:15

1 Answer 1

5

Try to wait for method too:

async getTreeView(){
    await fetch("myurl /*just a URL */", 
        {
            method: 'GET',
        })
        .then((response) => response.json())
        .then((data) => {
            console.log('1. GOT DATA');
            this.tree = JSON.parse(data.tree);
            this.setUpTree();
            console.log('3. SET UP COMPLETE');
        })
    }
}

in mounted hook:

async mounted(){
    await this.getTreeView();
    console.log('4. TREE LOADED AND VISIBLE');
}
Sign up to request clarification or add additional context in comments.

2 Comments

Now this works! But I don't get it at first: why the "double await"? Why the await on getTreeView() in mounted is not enough? Thanks
Because you need to wait till method resolve, so other lines want execute till then

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.