Initiate a POST request to download the file upon clicking the button

How can I initiate a file download when a button is clicked?

During testing, I noticed that sending a GET request using

<Link href="/api/generate-pdf">
works perfectly and the PDF file gets saved. However, when I use a button to hit the API, the download does not start.

This is how my button looks in a Next.js 13 Client Component:

function generatePdf() {
    fetch("/api/generate-pdf", {
      method: "POST",
      headers: {
        "Content-type": "application/pdf",
      },
      body: JSON.stringify(store),
    })
}

<Button onClick={generatePdf} type="button">
    Generate PDF
</Button>

API Route Handler:

export async function POST(request: Request) {
  console.log("/api/generate-pdf POST Request")
  try {
    // ...
    // generate the pdf file
    const generatedPdf = doc.output("blob")
    const filename = "pac.pdf"
    const res = new Response(generatedPdf, {
      status: 200,
      headers: {
        "Content-Type": "application/pdf",
        "content-disposition": `attachment; filename="${filename}"`,
      },
    })
    return res
  } catch (error) {
    console.log(error)
    return NextResponse.json("Internal Error", { status: 500 })
  }
}

Answer №1

It seems like the issue you are facing is related to how the fetch API handles file downloads compared to direct links. When you click a button, the fetch API sends a request and receives a response, but it does not automatically initiate the file download like a direct link would.

To work around this, you can adjust your generatePdf function to create a Blob object from the response and then generate a URL for that Blob. One approach is to programmatically simulate a click on a hidden anchor element that references this URL to trigger the file download, similar to this:

async function generatePdf() {
  const response = await fetch("/api/generate-pdf", {
    method: "POST",
    headers: {
      "Content-type": "application/pdf",
    },
    body: JSON.stringify(store),
  });

  const blob = await response.blob(); // creates a new Blob object
  const url = window.URL.createObjectURL(blob); 
  const a = document.createElement("a"); 
  a.href = url; 
  a.download = "yourPDF.pdf";  
  a.click(); 
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I need assistance in locating an error; the error message states that $ is not defined and an object is expected

Issue with $ not being defined, object expected.. I am trying to verify if all sets of radio buttons are checked when a button is clicked! Please help. <script type="text/javascript> $(document).on('click', 'form', function () { ...

"Troubleshooting why the jQuery Click Function is malfunctioning specifically in

Can someone help me troubleshoot this animate out script? It works fine on chrome, but not on Firefox and I can't seem to figure out why. Any suggestions? The script is designed to animate certain elements when a specific link is clicked. <scrip ...

What part of the system generates sessions and cookies?

Is the following statement accurate? When developing a website, I utilize frontend javascript to create cookies and backend languages such as php or ruby to manage sessions? If this is correct, does the creation of sessions involve the browser generating ...

Could you walk me through the details of this React function?

Currently, I have a function in place that retrieves products from the database to display on the eCommerce website's product page. Now, I am working on creating a similar function for user sign-in. Could you lend me a hand with this? I'm still ...

Accessing Session Objects in Struts2 Using a Different Session Object as a Key

I am fairly new to working with Struts2 and currently, I am faced with the challenge of retrieving a session object using a dynamic session key. Here's how my application flow goes: The user will trigger the action from their browser http://localhos ...

What is the best way to retrieve unique values from my MongoDB database?

My goal is to retrieve all the values of the property "Alimento" in my application. { "foods": [ { "_id": "6318c906904b22a684659009", "Alimento": "Papinha Infantil de Amei ...

Interactive Javascript dropdown helper on change

I am currently experimenting with a JavaScript onchange method, as I am relatively new to coding. My goal is that when I select "ID Type," the input text should change to "passport," and when I select "South African ID," the input should switch to "South ...

Mocking objects in unit test cases to simulate real-life scenarios and test the

How do I pass a mocked event object and ensure it is validated? onCallFunction() { const eventValue = event; if (!eventValue.relatedTarget || !eventValue.relatedTarget.last.contain('value')) { super.onCallFuncti ...

Tips for preventing useEffect from triggering a route?

Recently delving into reactjs, I stumbled upon a situation in the code where the route alerts messages twice. I'm seeking advice on how to prevent this issue, please disregard the redux code involved. Any suggestions? Index.js import React from &apos ...

Troubles encountered while processing STL file readers

Utilizing STLLoader.js, I am able to render components successfully, however, they all appear with one uniform color which does not resemble real-world components. The image above showcases my implementation in Three.js using STLLoader.js (Binary STL file ...

The comparison between createElement() and AJAX response

Currently, my website has a login form that updates the page with user data through AJAX after successful login. To maintain semantic integrity, I use JavaScript to remove the login form from the page once the user is logged in. However, when the user lo ...

Separate the string by commas, excluding any commas that are within quotation marks - javascript

While similar questions have been asked in this forum before, my specific requirement differs slightly. Apologies if this causes any confusion. The string I am working with is as follows - myString = " "123","ABC", "ABC,DEF", "GHI" " My goal is to spli ...

The Firebase Login functionality is experiencing issues on the deployed Next.js application, although it functions correctly when running locally

After developing a Next.js app with Firebase Google login functionality, everything was running smoothly in my local environment. However, upon deploying it to Railway and Vercel, the login feature seemed to malfunction. Whenever a user attempted to click ...

Sending data between components in Next.js layout.tsx

Trying to figure out how to pass properties between a page and a layout in Next.js has got me scratching my head. The situation I'm facing is as follows: I've got a standard Material UI stepper component (you can find it here: link) in my layou ...

Exploring how to iterate through multiple arrays simultaneously in JavaScript

I have a specific problem with processing two sets of array objects to achieve a desired output. var parts={"Glenn": [12,22,32], "Ryan": [13,23,33], "Steve K": [14], "Jerom":[15,25,35], }; var labor={ "Glenn": [12,22,32], "Ryan": [13,23,33], "Steve K": [ ...

The JavaScript filter function will only return arrays that have matching IDs

How can I filter out book data based on the author's id? I have a list of books with various author ids, and I want to only return the books that match a specific author id. However, my current filtering method doesn't seem to work correctly as i ...

Creating a factory class in Typescript that incorporates advanced logic

I have come across an issue with my TypeScript class that inherits another one. I am trying to create a factory class that can generate objects of either type based on simple logic, but it seems to be malfunctioning. Here is the basic Customer class: cla ...

Is it possible to add a computed value to the bar's end in Chart.JS?

I'm creating a bar graph that has two bars representing different weeks. Currently, it looks like this: https://i.stack.imgur.com/6Avni.png However, I want it to look like this: https://i.stack.imgur.com/TAVqe.png In order to achieve the desired r ...

Empty initial value for first item in array using React hooks

My goal is to store an array that I retrieve from an API in a useState hook, but the first entry in my array always ends up empty. The initial array looks like this: (3) ["", "5ea5d29230778c1cd47e02dd", "5ea5d2f430778c1cd47e02de"] The actual data I recei ...

Issue with Angular Swiper carousel: Error message pointing to node_modules/swiper/angular/angular/src/swiper-events.d.ts

I am attempting to implement a carousel in Angular using Swiper (). An error message is appearing: Error: node_modules/swiper/angular/angular/src/swiper-events.d.ts:3:50 - error TS2344: Type 'SwiperEvents[Property]' does not meet the constraint ...