javascriptjspdfjspdf-autotable

jsPDF show loading while processing. Promise does not wait


I'm using JSPDF and autotables plugin for PDF reports. While the PDF generation is happening I'm trying to show a loading image. Unfortunately, the loading is ignored even when trying with async().

function createPDF(){
  return new Promise(resolve => {
   var doc = new jsPDF();
    doc.autoTable({
        body: [
            ['Elmo', 'Hello'],
            ['Bert', 'The Muppet Show.']
        ]
    });
    
    // mimik time for processing
    setTimeout(function(){
      console.log('wait time for loading image')
    }, 8000);

    doc.save('table.pdf');
    resolve('resolved');

    });
}

async function asyncPDF() {
  document.getElementsByClassName('img__loading')[0].style.display = 'block';
  var result = await createPDF();
  document.getElementsByClassName('img__loading')[0].style.display = 'none';
}

document.getElementById('save').addEventListener("click", asyncPDF );
.img__loading{
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/3.1.1/jspdf.plugin.autotable.min.js"></script>


<button id="save">save</button>
<img src="https://ui-ex.com/images/transparent-background-loading.gif" class="img__loading">

The question is why is the loading image not showing up? And why does it start working when wrapping the save() and resolve() inside the timeout?

  setTimeout(function(){
      doc.save('table.pdf');
      resolve('resolved');
  }, 8000);

Solution

  • Use promise.then instead of async .And for testing your setTimeout was wrong place.You need to wrap with resolve .While on click your async function trigger all the inner calls.so loading as been immediately disappear after present that why wrap with in then function.then only detect the event finished from promise

    function createPDF(){
      return new Promise(resolve => {
       var doc = new jsPDF();
        doc.autoTable({
            body: [
                ['Elmo', 'Hello'],
                ['Bert', 'The Muppet Show.']
            ]
        });
    
          console.log('wait time for loading image')
    
    
        doc.save('table.pdf');
        setTimeout(()=>{
        resolve('resolved');
        },3000)
    
        });
    }
    
    function asyncPDF() {
      document.getElementsByClassName('img__loading')[0].style.display = 'block';
      createPDF().then(()=>{
      document.getElementsByClassName('img__loading')[0].style.display = 'none'})
    }
    
    document.getElementById('save').addEventListener("click", asyncPDF );
    .img__loading{
      display: none;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/3.1.1/jspdf.plugin.autotable.min.js"></script>
    
    
    <button id="save">save</button>
    <img src="https://ui-ex.com/images/transparent-background-loading.gif" class="img__loading">