0

In my project, I want the user to be able to download a document when he clicks on a button.

enter image description here

Project Structure:

enter image description here

public/client.js

console.log('Client-side code running');

const button = document.getElementById('myButton');
button.addEventListener('click', function(e) {
  console.log('button was clicked');

  fetch('/clicked', {method: 'POST'})
    .then(function(response) {
      if(response.ok) {
        console.log('Click was recorded');
        return;
      }
      throw new Error('Request failed.');
    })
    .catch(function(error) {
      console.log(error);
    });
});

public/index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Report Generation</title>
  </head>
  <body>
    <h1>Download your document!</h1>
    <button id="myButton">Click me!</button>
  </body>
  <script src="client.js"></script>
</html>

server.js

    console.log('Server-side code running');

    const express = require('express');
    const createDocumentService = 

    const app = express();

    // serve files from the public directory
    app.use(express.static('public'));

    // start the express web server listening on 8080
    app.listen(8081, () => {
      console.log('listening on 8080');
    });

    // serve the homepage
    app.get('/', (req, res) => {
      res.sendFile(__dirname + '/index.html');
    });
 app.get('/download', function(req, res){
         setTimeout(() => {
          res.download(path.join(__dirname, 'docs/doc1.txt'), function (err) {

              console.log(err);

          });
      }, 500)
      });


    app.post('/clicked', (req, res) => {
      const click = {clickTime: new Date()};
      console.log(click);

      setTimeout(() => {
          res.download(path.join(__dirname, 'docs/doc1.txt'), function (err) {

              console.log(err);

          });
      }, 500)
    });

After running the app and clicking the button:
enter image description here

When the user clicks on the button, he should see the report file being downloaded thanks to:

In client.js

button.addEventListener('click', function(e) {
  console.log('button was clicked');

  fetch('/clicked', {method: 'POST'})
    .then(function(response) {
      if(response.ok) {
        console.log('Click was recorded');
        return;
      }
      throw new Error('Request failed.');
    })
    .catch(function(error) {
      console.log(error);
    });
});

In service.js:

app.post('/clicked', (req, res) => {
      const click = {clickTime: new Date()};
      console.log(click);

      setTimeout(() => {
          res.download(path.join(__dirname, 'docs/doc1.txt'), function (err) {

              console.log(err);

          });
      }, 500)
    });

But, the document doesn't get downloaded.
However, when I connect to

localhost:5353/download

The same code/logic I wrote for downloading the document and which is written inside the button POST route, works perfectly and the document does get downloaded.
So I don't really see why the same code is working for one "normal" route and isn't working for the other route that depends on the button.

Thank you!

2
  • I had a couple questions: Why do you use setTimeout? Why dou you need two separate services? Why you had a console log on port 8080 and configure 8081? Commented Jun 15, 2019 at 14:32
  • 1
    @ontananza I use set-time out for a purpose that isn't explained in this question. I can be removed and nothing will change. The console log part is a typo. And the services thing I didn't really get what you mean by "two separate services" Commented Jun 15, 2019 at 15:05

1 Answer 1

2

You cannot download file using ajax cause Javascript doesn't have right to write to file. You can just use a href link or use the window.location it will work fine.

HTML:

<a href="/download" class="button">Click me!</a>

Use a .button class to style the link as a button.

JS:

button.addEventListener('click', function(e) {
  console.log('button was clicked');
  window.location="./download"
  // or window.open(url, '_blank') for new window.
});
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the info! I used the html solution, it seems simple. Can you please explain 'You cannot download file using ajax cause Javascript doesn't have right to write to file.' and its relation to my code? I ddon't just want to solve the issue i want to understand why it doesn't work in detail :)) thank you, anyways
And why doesn't this work: <button href="/download">Click me!</button>
button has no href attributes in html, w3.org/TR/html52/sec-forms.html#the-button-element

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.