Qiuzman
Qiuzman

Reputation: 1761

BeforeRouteEnter not loading data to variable

I have set up a web API that is sending data correctly, however, my vuejs app has a data table component which I do an API call with Axios using the BeforeRouteEnter hook but the data from the response does not save to my data variable.

Is it such that the Data variables such as my array called queryResult isn't loaded until after my get request hence the reason it cannot save to it? I also tried to call the Axios code and variable update as a method and that did not work as it did not recognize the method queryDB for some reason so again it leads me to believe my timing is off.

My code is as follows:

<template id="dashboard">
    <div>
        <v-card>
            <v-card-title>
                <v-text-field v-model="search"
                              append-icon="mdi-magnify"
                              label="Search"
                              single-line
                              hide-details></v-text-field>
            </v-card-title>
            <v-data-table :headers="headers"
                          :items="queryResult"
                          :search="search"></v-data-table>
        </v-card>
    </div>
</template>
    const dashboard = Vue.component('dashboard',
        {
        template: '#dashboard',
            data() {
                return {
                    userID: 'SB',
                    password: 'Yellow',
                    search: '',
                    headers: [
                        { text: 'ID', align: 'start', filterable: true, value: 'ID'},
                        { text: 'USERNAME', value: 'USERNAME' },
                        { text: 'FIRST_NAME', value: 'FIRST_NAME' },
                        { text: 'LAST_NAME', value: 'LAST_NAME' },
                    ],
                    queryResult: [],
                }
            },
            beforeRouteEnter(to, from, next) {
                axios.get(window.location.origin + '/home/DapperDatatableLoad', {
                    params: {}
                })
                    .then(function (response) {
                        queryResult = response.data;
                    })
                    .catch(function (error) {
                        console.log(error);
                    });
                next()
            },
            methods: {
                queryDB: function () {
                    axios.get(window.location.origin + '/home/DapperDatatableLoad', {
                        params: {
                            
                        }
                    })
                        .then(function (response) {
                            queryResult = response.data;
                        })
                        .catch(function (error) {
                            console.log(error);
                        });
                }
            }
        });

Upvotes: 0

Views: 2108

Answers (2)

Farid
Farid

Reputation: 463

You don't have access to data reactive variables inside beforeRouteEnter but you can change the them inside next function. So Your code:

const dashboard = Vue.component('dashboard',
        {
        template: '#dashboard',
            data() {
                return {
                    userID: 'SB',
                    password: 'Yellow',
                    search: '',
                    headers: [
                        { text: 'ID', align: 'start', filterable: true, value: 'ID'},
                        { text: 'USERNAME', value: 'USERNAME' },
                        { text: 'FIRST_NAME', value: 'FIRST_NAME' },
                        { text: 'LAST_NAME', value: 'LAST_NAME' },
                    ],
                    queryResult: [],
                }
            },
            beforeRouteEnter(to, from, next) {
                let data = null
                axios.get(window.location.origin + '/home/DapperDatatableLoad', {
                    params: {}
                })
                    .then(function (response) {
                        data = response.data;
                    })
                    .catch(function (error) {
                        console.log(error);
                    });
                next((vm)=>{
                   vm.queryResult = data
                })
            },
            methods: {
                queryDB: function () {
                    axios.get(window.location.origin + '/home/DapperDatatableLoad', {
                        params: {
                            
                        }
                    })
                        .then(function (response) {
                            queryResult = response.data;
                        })
                        .catch(function (error) {
                            console.log(error);
                        });
                }
            }
        });

Upvotes: 1

Marcello B.
Marcello B.

Reputation: 4440

What I think you are saying is that the route loads before your data is present.

This makes sense as axios.get is asynchronous. Meaning that while axios.get is requesting data from the server, the main thread is still executing code. Then when axios.get receives data it triggers the .then callback.

In your case, your next command is next() which tells the router to go ahead and move forward in routing. This means that while axios.get is retrieving data you have already called next().

If you want to wait for axios to get the data first you need to move next() to within the callback function.

beforeRouteEnter(to, from, next) {
    axios.get(window.location.origin + '/home/DapperDatatableLoad', {
        params: {}
    })
        .then(function (response) {
            next();
            this.queryResult = response.data; //Notice that `queryResult` is referred to with `this.`
        })
        .catch(function (error) {
            next();
            console.log(error);
        });
},

Another solution is to use await syntax instead

async beforeRouteEnter(to, from, next) {
    try{
        let response = await axios.get(window.location.origin + '/home/DapperDatatableLoad', {
            params: {}
        });
    } catch (error){
        console.log(error);
    }
    this.queryResult = response.data;       

    next();
},

Upvotes: 1

Related Questions