0

I have list and each clicked item triggers different API request. Each request have different duration. On success I'm displaying some data.

Issue is that when I click on item#1 which takes approx 6000 to load, and just after on item#2 which takes 2000 to load, I will have the last clicked item displayed - which is item#2 because it has already loaded and once item#1 has received data my data will change to that. This is wrong as I want to display data from the latest click.

This is how I handle event:

 newList.on('click', 'li', (e) => {
                let id = $(e.currentTarget).data("id");
                store.getCharacterDetails(id).then(docs => {
                    this.clearDetails();
                    this.charDetails = docs;
                    this.displayDetails(this.charDetails);
                })

My API is a simulation from store object.

I suppose this works as expected but I do want the last triggered request to be valid.

elJot
  • 11
  • 3
  • 4
    Then logically you'd want to cancel any previous requests that are outstanding when another request should begin. – Taplar Nov 29 '18 at 21:25
  • 1
    You'll need to give us more information about how `getCharacterDetails` works if you want more granular advice. However, about the general problem of canceling a running promise, see https://stackoverflow.com/q/30233302/215552 – Heretic Monkey Nov 29 '18 at 21:29

2 Answers2

0

A crude and simple method can be creating an array and pushing the IDs and after the asynchronous operations you can just check if it is the latest click or not. But pitfall is that if clear and displayDetails takes much time and if someone click while it was clearing and displaying it will not register the latest click.

Anyway, here is the code maybe you can make something better out of it.

var latestClick = [];
newList.on('click', 'li', (e) => {
    let id = $(e.currentTarget).data("id");
    latestClick.push(id);
    store.getCharacterDetails(id).then(docs => {
        if(id === latestClick[latestClick.length - 1]){
            this.clearDetails();
            this.charDetails = docs;
            this.displayDetails(this.charDetails);
            latestClick = [];
        }
    })
})
Aritra Chakraborty
  • 12,123
  • 3
  • 26
  • 35
0

Make charDetails an object that keeps all of the results, keyed by the ids. Keep track of the last clicked id.

// in constructor
this.charDetails = {};
this.lastId = null;

newList.on('click', 'li', (e) => {
    let id = $(e.currentTarget).data("id");
    this.lastId = id;
    if (this.charDetails[id] === id) {  // don't cancel requests, cache them!
        this.displayDetails(this.charDetails[id])
    } else {
        store.getCharacterDetails(id).then(docs => {
            // this runs later, cache the result
            this.charDetails[id] = docs;
            if (id === lastId) {  // only update UI if the id was last clicked
                this.displayDetails(docs)
            }
        });
    }
});
danh
  • 62,181
  • 10
  • 95
  • 136