PeachScript / vue-infinite-loading

An infinite scroll plugin for Vue.js.
https://peachscript.github.io/vue-infinite-loading/
MIT License
2.67k stars 368 forks source link

Duplicate request being sent, this.page ignored #258

Open jonny7 opened 5 years ago

jonny7 commented 5 years ago

I am experiencing that on occasions my infinite-load is duplicating data sets. I find that it most often occurs when moving from updating a single record to viewing the whole list of items. I have the following code in place

<infinite-loading class="col-sm-6 mx-auto" @infinite="infiniteHandler" spinner="waveDots"></infinite-loading>
infiniteHandler($state) {
      HTTP.get("group/" + this.$route.params.id + "/metric", {
        params: {
          page: this.page
        }
      })
        .then(({ data }) => {
          console.log(this.page)
          if (data.items.metrics.length > 0) {
            this.page += 1;
            this.responseEmpty = false;
            this.metrics.push(...data.items.metrics);
            this.filtered = this.metrics;
            $state.loaded();
          } else {
            $state.complete();
          }
        })
        .catch(e => catchError(e));
    }

When debugging this, I saw in the console that this.page read out as expected

1
2
3

But in the network activity I am seeing this:

image

I'm following the docs and enjoying infinite-loader, but I'm unsure as to why this is occurring or if I'm missing some kind of configuration. My current version is 2.4.3

I'm going to use this in the mean time in case anyone wants a solution, although this will stop deplicates, it doesn't fix the missing page number requests in the network traffic.

const unique= Array.from(new Set(metrics.map(m => m.id)))
 .map(id => {
   return metrics.find(m => m.id === id)
 })
mortzion commented 5 years ago

I guess the error is happening because you are sending the second request before the first response is back(which updates this.page). Try updating this.page value before sending the request. Like this.

infiniteHandler($state) {
      HTTP.get("group/" + this.$route.params.id + "/metric", {
        params: {
          page: this.page++
        }
      })
        .then(({ data }) => {
          console.log(this.page)
          if (data.items.metrics.length > 0) {
            this.responseEmpty = false;
            this.metrics.push(...data.items.metrics);
            this.filtered = this.metrics;
            $state.loaded();
          } else {
            $state.complete();
          }
        })
        .catch(e => catchError(e));
    }
jonny7 commented 5 years ago

Hi @mortzion

I can look at this, but I am following the way the docs state: https://peachscript.github.io/vue-infinite-loading/guide/start-with-hn.html

But please correct me if I'm wrong. Are the docs wrong?

Tes3awy commented 5 years ago

Hello @jonny7,

I want to ask you a question as I was debugging the plugin because I had a similar issue and I assume you were trying to call the infiniteHandler twice one in the methods and the other in mounted hook, Am I correct?

jonny7 commented 5 years ago

Hi @Tes3awy

No I don't have it in any life-cycle hooks

Tes3awy commented 5 years ago

@jonny7 It's very weird as I was calling it twice so that's why I was getting duplicates. I was trying it on a clean vue install with JSON placeholder. Here is my demo repo if you would like to try it out.

trasigor commented 5 years ago

@Tes3awy As I can see in your code, you asking for the same data at every request, starting from the first record, but increasing number of records to return. You should ask only for the next batch of record after the last you have on your frontend.

@jonny7 I think your problem could be solved on the backend code. Do you process GET variable page ? You can check it without vue on your browser by requesting "group/" + this.$route.params.id + "/metric?page=" + 1 (2, 3 ... and so on). Just replace this.$route.params.id with whatever it should be.

jonny7 commented 5 years ago

Hi @trasigor

I'm not sure how that would work? The server works fine, as you can see from the screen shots in my Q, The page variable request seems to be wrong or misaligned with what the console sees. I am following the docs though, so unsure what the problem with the JS is.

Tes3awy commented 5 years ago

Hello @trasigor,

I am afraid I don't understand you. Can you please elaborate with some code? Thank you.

mortzion commented 5 years ago

@jonny7 Have you tried the changes I suggested?

Hi @mortzion I can look at this, but I am following the way the docs state: https://peachscript.github.io/vue-infinite-loading/guide/start-with-hn.html But please correct me if I'm wrong. Are the docs wrong?

I don't think the docs are wrong, its just that in the docs example, the interface doesn't allow for a request being made before the previous one arrives. Something in your code allows that, like the change between updating a record and viewing the whole list.

wimil commented 5 years ago

The same happens to me when loading the first results makes me 2 requests, then when I move and reach the last one it makes me 2 requests again and so on

PeachScript commented 5 years ago

@jonny7 @wimil it would be better if you could provide a live demo here

emad-sure commented 4 years ago

@mortzion , i didn't update this.page but added v-if in infinite-loading <infinite-loading v-if="!loading" />