2

I am reading the data from an API and downloading a file. I want to save the same file in public folder of react application.

enter image description here

 this.state = {
      fileDownloadUrl: null,
      fileName: '',
    };

below is the method.

 downLoadFile(e) {
    e.preventDefault();
    axios
      .get(
        'http://localhost:8080/file_download/en'
      )
      .then((res) => {
       var output = res.data;
        const blob = new Blob([output]);
        const fileDownloadUrl = URL.createObjectURL(blob);
        this.setState({ fileDownloadUrl: fileDownloadUrl }, () => {
          this.dofileDownload.click();
          URL.revokeObjectURL(fileDownloadUrl);
          this.setState({ fileDownloadUrl: '' });
        });
      });
  }

code for downloading the file.

           <a
            className="hidden"
            download={this.state.fileName + '.json'}
            href={this.state.fileDownloadUrl}
            ref={(e) => (this.dofileDownload = e)}
          >
            download it
          </a>

Is there anyway I can modify the code so that file can be saved in the public folder of react application. later this file will be used for translation.

Shruti sharma
  • 199
  • 6
  • 21
  • 67

3 Answers3

2

There's no way to automatically download a file and save it in a specific location on your hard disk from a frontend app running inside a browser. The users of your app will decide how the file is saved based on their browser settings.

If you're trying to achieve that kind of thing, then that's wrong and you should consider another approach.

Cuong Vu
  • 3,423
  • 14
  • 16
  • 1
    can you help me with this question as well, please. https://stackoverflow.com/questions/70432739/need-to-pass-the-execution-of-code-to-get-output-in-javascript – Shruti sharma Jan 22 '22 at 19:58
1

It's not possible because this poses a security risk.

Most of the OS will defaults the download to download folder.

Pure browser-JavaScript is not be able to get information about the user's filesystem. The default download path might also contain sensible information, which is risky.

  • can you suggest somework around? – Shruti sharma Jan 22 '22 at 19:29
  • 1
    Instead of downloading your locales as files , I'm assuming you will require only few locales to save. You can use browser local storage to save it by JSON. Refer the doc https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Client-side_storage – Srimurugan Subramanian Jan 22 '22 at 19:54
0

To sum up the question, the challenge is to fetch or otherwise produce certain static file assets for React to consume.

As other answers pointed out, it's impossible to do from React itself. I'd add, if it were possible, that would be inefficient, unsafe and insecure.

Architecturally, it's best to create a file-generating script and run it before the React application's build step.

I'm using such setup myself. For example, if you checked my package.json I've got scripts:

{
  "scripts": {
    "--------- BUILD ---------": "",
    "build": "npm run ops && run-s build:*",
    "build:remix": "remix build",
    "build:css": "npm run generate:css",
    "--------- DEV ---------": "",
    "dev": "npm run ops && run-p dev:*",
    "dev:remix": "cross-env NODE_ENV=development remix dev",
    "dev:css": "npm run generate:css -- --watch",
    "generate:css": "sass styles:app/styles app/components",
    "format": "prettier --write .",
    "--------- TEST ---------": "",
    "start:mocks": "cross-env NODE_ENV=production node --require ./mocks --require dotenv/config ./build/server.js",
    "test": "vitest run --coverage",
    "test:e2e:dev": "start-server-and-test dev http://localhost:3000 \"cypress open\"",
    "pretest:e2e:run": "npm run build",
    "test:e2e:run": "cross-env PORT=8811 start-server-and-test start:mocks http://localhost:8811 \"cypress run\"",
    "--------- LINT ---------": "",
    "lint": "eslint --cache --cache-location ./node_modules/.cache/eslint .",
    "typecheck": "tsc -b && tsc -b cypress",
    "validate": "run-p \"test -- --run\" lint typecheck test:e2e:run",
    "--------- OPS ---------": "",
    "ops": "run-p ops:*",
    "ops:static": "node ./ops/extract-static-data.mjs",
    "ops:search": "node ./ops/extract-search.mjs",
    "ops:rss": "node ./ops/extract-rss.mjs"
  }
}

notice how ops group of scripts is triggered before the React build step. I generate static fresh files:

  • lump of all h2 heading strings for aside to set currently active anchor
  • all MDX front matter lump of all articles for rendering MDX outside normal routes (article lists, search etc.)
  • the final HTML of RSS feed; I render HTML with all remark goodies such as syntax titles, syntax highlighting and typography
  • compile the search data file and index file (for warm starts) for fuse.js

I'd fetch locales this way too: npm-triggered script would fetch and atomically save a file straight into /public/.

It's done during build-time rather than runtime to simplify the setup and lower the server bill. I disagree with Mr. Dodds in this aspect; more so, runtime libraries such as mdx-bundler don't even support pure ESM, so actually, runtime-oriented approaches often don't even work. For example, if you take the same Mr. Dodds' blog, it doesn't have the current anchor tracking in single posts or site-wide search or automated typography processing.

PS. Interestingly, if you look at the static site generators, 11ty lets you fetch extra sources from the 11ty config itself, that's where you would fetch the locales of yours on 11ty.

revelt
  • 2,312
  • 1
  • 25
  • 37