Uncaught ReferenceError: Function is not defined

I am currently in development on a web portal using Django. I was using jsPDF-autotable library via github to convert my tables into a pdf file. However, I have tried multiple ways - via js file:

html file:

script src="/static/js/volumerpt_export_pdf.js" type="module"></script

js file:

import jsPDF from 'jspdf'
import 'jspdf-autotable'
function generatePDF() {
    var doc = new jsPDF();
    doc.autoTable({ html: '#volume-results' });
    doc.save('table.pdf');
}

and <script> in my html:

<script type="module">
        import jsPDF from 'jspdf'
        import 'jspdf-autotable'

        function generatePDF() {
            var doc = new jsPDF();
            doc.autoTable({ html: '#volume-results' });
            doc.save('table.pdf');
        }
</script>

my html button:

<button onload="generatePDF()" class="btn btn-primary">Export</button>

Neither work and give the same error. I have followed the docs on jspdf-autotable’s page:
https://github.com/simonbengtsson/jsPDF-AutoTable

This is the error if I change my button to onclick:

Uncaught ReferenceError: generatePDF is not defined
    at HTMLButtonElement.onclick (dailyvolume:204)

This is the error if I change my button to onload:

Uncaught TypeError: Failed to resolve module specifier "jspdf". Relative references must start with either "/", "./", or "../".

Hi @schulzy175, anything defined in a module is scoped to that module, so it won’t be available to iline JS; a quick and dirty fix would be to explicitly expose that function to the global scope:

// In you JS file
window.generatePDF = generatePDF

However the cleaner solution would be adding an event listener so you don’t have to pollute the global scope in the first place (note that your JS needs to be included at the bottom of the page then):

<button id="generate-pdf">export</button>
...
<script type="module">
  import jsPDF from './path/to/jspdf/jspdf.mjs'
  import './path/to/jspdf-autotable/jspdf-autotable.mjs'

  const button = document.getElementById('generate-pdf')

  function generatePDF () {
    const doc = new jsPDF()

    doc.autoTable({ html: '#volume-results' })
    doc.save('table.pdf')
  }

  button.addEventListener('click', generatePDF)
</script>

Edit: As for the imports, you have to specify the actual path to where the module is located. The documentation probably assumes you’re using a module bundler such as webpack, where you can include modules just by their name. If you’re not using a module bundler the library will have to support native modules though.

The editing toolbar has a code icon that looks like </>. That gives you three backticks at the start and end of a code section.

If you want to help the syntax highlighting, you can use ```html or ```css or ```javascript at the start instead of just ```

You can also put code inline by using a single backtick to delimit the inline code.

I’ve taken the opportunity to update your first post with those code presentation improvements.

1 Like

I greatly appreciate the reply @m3g4p0p and that is very kind of you @Paul_Wilkins.

Sadly, with your solution, it seems Pycharm won’t recognized the path to the js file (located within node_modules). Considering it’s Django and Pycharm, I feel the solution may be more python related. I’ve already included my node_modules in my project structure, but Pycharm refuses to recognize the path. The saddest part about this ~10 line script is that all I need to do is to get python/Pycharm to recognize the location of the imports - extremely frustrating.