0

I have a html form and I want to create a json-file with data introduced in html fields.
Right now, it is visible in console json-text but it doesn't create a new json-file with this content.
Also,I have an error, Uncaught ReferenceError: require is not defined.
    // get the form element from dom
    const formElement = document.querySelector('form#forms')

    // convert the form to JSON
    const getFormJSON = (form) => {
      const data = new FormData(form);
      return Array.from(data.keys()).reduce((result, key) => {
        if (result[key]) {
          result[key] = data.getAll(key)
          return result
        }
        result[key] = data.get(key);
        return result;
      }, {});
    };

    // handle the form submission event, prevent default form behaviour, check validity, convert form to JSON
    const handler = (event) => {
      event.preventDefault();
      const valid = formElement.reportValidity();
      if (valid) {
        const result = getFormJSON(formElement);
        // handle one, multiple or no files uploaded
        const images = [result.images].flat().filter((file) => !!file.name)
        // handle one, multiple or no languages selected
        const languages = [result.languages || []].flat();
        // convert the checkbox to a boolean
        const isHappyReader = !!(result.isHappyReader && result.isHappyReader === 'on')

        // use spread function, but override the keys we've made changes to
        const output = {
          ...result,
          images,
          languages,
          isHappyReader
        }
        console.log(output)
      }
    }

    formElement.addEventListener("submit", handler)



    const fs = require('fs');
    const dataNew = JSON.stringify(output);
    fs.writeFile('output.json', dataNew, (err) => {
    if (err) {
        console.log("error")
        throw err;
    }
    console.log("JSON data is saved.");
});
  </script>
</body>
  • You are trying to mix nodejs modules like "fs" and client side javascript. You can't use nodejs in client side javascript as it is made to run on server side. – KreutzerCode Mar 24 '22 at 11:05

1 Answers1

0

It seems you are on the frontend. You can't write files like this because of security. This would result in every website with some JavaScript being potentially able to write files to your system and you really don't want that. Additionally fs is a Node API that is not available in the browser.

One option would be to download the JSON file from the frontend which you could do using the following code:

/**
 * Download a JSON file.
 * @param {sting} filename filename
 * @param {any} obj any serializeable object
 */
function downloadJson(filename, obj) {
  // serialize to JSON and pretty print with indent of 4
  const text = JSON.stringify(obj, null, 4);

  // create anchor tag
  var element = document.createElement("a");
  element.setAttribute(
    "href",
    "data:application/json;charset=utf-8," + encodeURIComponent(text)
  );
  element.setAttribute("download", filename);
  // don't display the tag
  element.style.display = "none";
  // add tag to document
  document.body.appendChild(element);
  // click it: this starts the download
  element.click();
  // remove the tag again
  document.body.removeChild(element);
}

window.addEventListener("DOMContentLoaded", (event) => {
  // Start file download.
  downloadJson("helloWorld.json", { hello: "World" });
});


If you add that to your page the save dialog will appear on a user's system. Here the one I am getting on Ubuntu:

Save dialog on Ubuntu for helloWorld.json

And here the content of the downloaded file: helloWorld.json content after download

Please read this thread on the pros and cons of using an approach like this.

Mushroomator
  • 6,516
  • 1
  • 10
  • 27
  • Please consider marking this as an [*accepted answer*](https://stackoverflow.com/help/someone-answers#:~:text=To%20accept%20an%20answer%3A&text=To%20mark%20an%20answer%20as,the%20answer%2C%20at%20any%20time.) if this worked for you :) – Mushroomator Mar 24 '22 at 11:12
  • Thank you! How can I put my json data from the console in the new created file instead of hello world? And how can I prevent the refresh page button from triggering the download? – Cosmina C. Mar 24 '22 at 12:04
  • Triggering the download: Remove this `window.addEventListener("DOMContentLoaded", (event) => { // Start file download. downloadJson("helloWorld.json", { hello: "World" }); });` to stop downloading every time the page loads this was just for demo purposes. You should call function `downdloadJson()` when you need it instead. – Mushroomator Mar 24 '22 at 12:09
  • Download your `output`: There is no need to get this from the console you already have the `output` variable with all the information in your `handler` method. Just pass that to `downloadJson()` like so `downloadJson("myoutput.json", output)` and it will download whatever you have stored in `output`. Please let me know if it works :) – Mushroomator Mar 24 '22 at 12:12
  • No, it does not work, if you have time to review I will appreciate it: https://codepen.io/cosminach/pen/LYexRXm?editors=1010 – Cosmina C. Mar 24 '22 at 12:45
  • Ok, I've looked into it, there are two things you need to change, then it works. just use `downloadJson("myoutput.json", output);` after your `console.log()` remove all that `window.addEventListener("DOMContentLoaded", (event) => { // Start file download. downloadJson("helloWorld.json", { hello: "World" }); });`. This will prevent the download from starting. And secondly in your HTML remove the `onclick="downloadJson()"` as this will call the method without parameters and thus download `undefined`. And you already have a form handler function so would be handling submit twice. Don't. – Mushroomator Mar 24 '22 at 13:03