-1

I'm grabbing json data using fetch and rendering list items with the results. The function containing fetch is triggered by a button. However, if I click it while the initial fetch is still going, data from it will be loaded on top of my new call.

I've used window.stop() to halt this behaviour but is there a better solution?

function updateTable() {

    fetch('/json')
    .then((response) => {return response.json()})
    .then((response) => { 
        response.records.forEach(el => {
            return '<li>' + el.Name + '</li>';
        })
    })
}

$('button').click(function(){
    window.stop();
    $('body').empty();
    updateTable()
})

Edited with answer: Upon re-reading the linked thread on using the new signal property with fetch, I updated my code to work with the new AbortController. The trick, documented here, is to re-define the controller whenever the function is called again. The advantage vs. window.stop() is that stoppage only affects this fetch.

var controller = "";
var signal = "";

function updateTable() {

  controller = new AbortController();
  signal = controller.signal;

    fetch('/json', {signal})
    .then((response) => {return response.json()})
    .then((response) => { 
        response.records.forEach(el => {
            return '<li>' + el.Name + '</li>';
        })
    })
}

$('button').click(function(){
    controller.abort();
    $('body').empty();
    updateTable()
})
east1999
  • 189
  • 5
  • 14
  • 1
    Disable the button while it's loading, or cancel the pending web request whenever you click the button. – weltschmerz Aug 20 '20 at 19:48
  • Answers should not be edited into the question. Instead, mark the correct answer as «accepted». Write your own answer, and mark it as accepted, if you found the solution yourself. – Andreas detests censorship Aug 20 '20 at 20:59
  • Sorry, but I couldn't add a new answer (question is blocked). Why even do all this? I'm sure it'd help others. – east1999 Aug 21 '20 at 08:41

1 Answers1

1

This could be done with a simple variable. That is used to determine if fetch is still processing.

var allRecords = [];
var processing = false;

function updateTable() {

    fetch('/json' )
    .then((response) => {return response.json()})
    .then((response) => { 
        processing = false;
        response.records.forEach(el => {
            return '<li>' + el.Name + '</li>';
        })
    })
}

$('button').click(function(){

    if(processing === false){
        processing = true;
        $('body').empty()
        updateTable()
    }
})
imvain2
  • 10,963
  • 1
  • 14
  • 19
  • Thank you. However, with a large amount of records, that still means `forEach` will not be stopped immediately. – east1999 Aug 20 '20 at 19:54