简体   繁体   中英

Vue data value not updating for in function use

So i'm trying to lazy load articles with infinite scrolling, with inertia-vue and axios, backend is laravel 6.0. Since I don't want to do unnecessary request i'm giving over the total amount of articles to the component. I'm also tracking the amount of already loaded articles in the component data.

props: {
    article_count: Number,
   },
data: function () {
    return {
        loaded: 0,
        scrolledToBottom: false,
        articles: [],
    }
},

The articles that are loaded are all being put into articles , and scrolledToBottom keeps track if the user has scrolled to the bottom. I have already checked if this refers to the vue component and has the data properties, which it does.

methods: {
    load: function (nextToLoad) {
        for (let i = nextToLoad; i < nextToLoad + 10; i++){
            if (this.loaded <= this.article_count){
                this.$axios.get(route('api_single_article', i))
                    .then(response => {
                        if (response.status == 200 && response.data != null) {
                            console.log(this.loaded);
                            this.articles.push(response.data);
                        }
                        this.loaded++;
                    })
                    .catch(error => {
                        if (error.response.status != 404) {
                            console.log(error);
                            console.log(this.loaded);
                            this.loaded++;
                        }
                    });
            }
        }
        console.log(this.loaded);
    },
    scroll: function () {
        window.onscroll = () => {
            let bottomOfWindow = document.documentElement.scrollTop + window.innerHeight === document.documentElement.offsetHeight;

            if (bottomOfWindow) {
                this.load(this.loaded + 1);
            }
        }
    }
}

The weird part is, that if i log this.loaded in the response / error arrow function it always returns 0. If i do it outside the response it also returns 0, but if i log this the loaded property has the supposed value after the loop has ran through, despite it being logged every time the loop is run. I have already showed this to a friend and he also couldn't fix it. The behaviour just seems weird to me and i don't know how else i should do, since i'm very inexperienced with vue.

Thanks for the help.

Might be a concurrency thing. Remember that the axios call is asynchronous so the loop will continue before the responses have been received.

So it could be the many responses are received at the same time and that loaded is then still 0 at that point. Looks like this won't be the case. Apparently JavaScript will process callbacks one after the other.

I'm not sure how JavaScript handles concurrent increments though so I can't exactly explain how that plays into effect here.

From your implementation, it looks like you'd want to turn the load function into an asynchronous function (using the async ) keyword and then use the await before the axios call to ensure that you have received a response before making another request.

For interest's sake, maybe have a look at your network tab and count how many requests are being made. I suspect there will be more requests made than this.article_count .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM