Reputation:
So I recently started learning HTML/JavaScript. I am trying to create a page where the information entered can then be stored in a PDF for saving/printing. I have had a lot of issues trying to get this to work, so I went in search of some basic code just so I could see that jsPDF works before continuing with my project. This is the code that I found:
// Create a function to generate the PDF
function generatePDF() {
const doc = new jsPDF();
doc.text('Hello, World!', 10, 10);
doc.save('my-document.pdf');
}
// Attach the function to the button click event
document.getElementById('cmd').addEventListener('click', generatePDF);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.3/jspdf.umd.min.js"></script>
<div id="abc">
<!-- Your content here -->
<p>Hello, World!</p>
</div>
<button id="cmd">Generate PDF</button>
The issue I have is that this is also giving an error when inspected through edges dev tools. This is the error I'm catching:
Uncaught ReferenceError: jsPDF is not defined at HTMLButtonElement.generatePDF
Being so new to this I really have no idea why it is giving me this error.
I have tried multiple different library references for jsPDF all to that same result.
Upvotes: 3
Views: 1175
Reputation: 401
I have the same issue in nodejs, I use this code
const jspdf = require('jspdf');
const file = new jspdf.jsPDF("p", "mm", "a4");
and it worked as intended
Upvotes: 0
Reputation: 8508
The latest released version of jspdf
is not 2.5.3
but 2.5.1
. Accordingly, I have inserted a new CDN. See here: https://www.npmjs.com/package/jspdf
jspdf
does not expose a class to you directly, instead, it places a property named jspdf
into the window
object as a global variable, from which we can instantiate the class. I have done this. Your code should now be functional.
// Create a function to generate the PDF
function generatePDF() {
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
doc.text('Hello, World!', 10, 10);
doc.save('my-document.pdf');
}
// Attach the function to the button click event
document.getElementById('cmd').addEventListener('click', generatePDF);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js" integrity="sha512-qZvrmS2ekKPF2mSznTQsxqPgnpkI4DNTlrdUmTzrDgektczlKNRRhy5X5AAOnx5S09ydFYWWNSfcEqDTTHgtNA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div id="abc">
<p>Hello, World!</p>
</div>
<button id="cmd">Generate PDF</button>
window.
object invocation optional?As @slebetman's comment also points out, since JavaScript searches for the invoked variable at every level, if your jspdf
variable is not declared, then the window.jspdf
parameter is invoked instead. You can read more about this behavior here: What's the difference between a global variable and a 'window.variable' in JavaScript? - Stack Overflow answer
I would like to highlight an important detail from the linked description, with which I can identify, questioning whether we are simplifying the code or not:
Since I have to double check whether it's a typo or not, I personally find it more readable to set
window.foo
directly. (Source)
Consequently, you can simplify your code by omitting the window.
invocation, but it's important to note that the creator of the jspdf
package declared the variable's value there.
// Create a function to generate the PDF
function generatePDF() {
const doc = new jspdf.jsPDF();
doc.text('Hello, World!', 10, 10);
doc.save('my-document.pdf');
}
// Attach the function to the button click event
document.getElementById('cmd').addEventListener('click', generatePDF);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js" integrity="sha512-qZvrmS2ekKPF2mSznTQsxqPgnpkI4DNTlrdUmTzrDgektczlKNRRhy5X5AAOnx5S09ydFYWWNSfcEqDTTHgtNA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div id="abc">
<p>Hello, World!</p>
</div>
<button id="cmd">Generate PDF</button>
Upvotes: 3