Connecting HTML/DOM with node.js - javascript

I'm trying to find a way to write to a text file using node.js but I was trying to get the input from the HTML DOM. How do you write the output from the DOM to a text file using fs.writeFile?
Here's some code that doesn't work but thought it might be relevant. Thanks
<h3>A demonstration of how to access a Text Field</h3>
<input id="myText">
<button onclick="myFunction()">Try it</button>
<script>
const fs = require('fs')
function myFunction() {
var content = document.getElementById("myText").value;
}
fs.writeFile('./test.txt', content, err => {
if(err){
console.log(err);
return
}
})
</script>

You cannot write file directly from a browser to local computers.
That would be a massive security concern.
*You also cannot use fs on client-side browser
Instead you get inputs from a browser, and send it to your server (NodeJs), and use fs.writeFile() on server-side, which is allowed.
What you could do is:
Create a link and prompt to download.
Send to server and response with a download.
Use native environment like Electron to able NodeJs locally to write into local computer.
What I assume you want to do is 1
Is that case you could simply do:
function writeAndDownload(str, filename){
let yourContent = str
//Convert your string into ObjectURL
let bom = new Uint8Array([0xef, 0xbb, 0xbf]);
let blob = new Blob([bom, yourContent], { type: "text/plain" });
let url = (window.URL || window.webkitURL).createObjectURL(blob);
//Create a link and assign the ObjectURL
let link = document.createElement("a");
link.style.display = "none";
link.setAttribute("href", url);
link.setAttribute("download", filename);
//Automatically prompt to download
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
writeAndDownload("Text you want to save", "savedData")

Related

How to save string from input to existing text JAVASCRIPT

I have html page, on that page I have input and button
I want to save the string in input into existing file like 'text.txt`
this is my html code
<input id="sub" dir="ltr" type="text" placeholder="type something">
<button id="myBtn" onclick="myFunction()" class="main-btn">Subscribe</button>
and this is my javascript function
<script>
function myFunction() {
const fs = require('fs')
let data = document.getElementById("sub").value + "\r\n";
fs.writeFile('Output.txt', data, (err) => {
if (err) throw err;
})
}
</script>
but it's not working
You can't just access the Filesystem from your browser.
Your options depend on what you are trying to achieve.
1. Save a txt file on the users local filesystem
You can create a "downloadable" element directly from JS. Depending on the browser the user will be prompted to allow downloads and/or where to store the file. You cannot access the file afterwards.
function download(filename, text) {
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
// Start file download.
download("hello.txt","This is the content of my file :)");
Source: https://www.codegrepper.com/code-examples/javascript/javascript+download+text+as+txt+file
2. Save data inside the browser so you can read/write whenever the users visits your website
The localstorage API can create small keyed objects (like 5-10 mb) on the user system. You can read/write anything to or from it that is serializable.
localStorage.setItem('myCat', 'Tom');
const cat = localStorage.getItem('myCat');
localStorage.removeItem('myCat');
Here: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
3. Save a file/data on your server
If you need the file on the server itself, you must create a backend with php, nodejs etc. Then you must implement an endpoint that accepts the data you want to save and inside nodejs you can import the "fs" and directly write files to it.
const fs = require('fs')
const content = 'Some content!'
fs.writeFile('/Users/joe/test.txt', content, err => {
if (err) {
console.error(err)
return
}
//file written successfully
})
Source: https://nodejs.dev/learn/writing-files-with-nodejs

React:write to json file or export/download [no server]

I got really confused with file I/O in JS/TS. most examples I see works with DOM and has browser-based solutions.
Also, I did not understand how to make fs work, it seems to need a webpack config, where I use CRA and do not want to eject.
in a React component I want to fetch some data from a server then save them as a JSON file in the project folder (the same path, root, public folder, no matter) or directly download (no button needed).
//data type just in case
inteface IAllData{ name:string; allData:IData[];}
so after fetching some data want to save them to name.json
public componentDidMount(){
this.fetchData().then(()=>this.saveData())
}
public async fetchData(){/* sets data in state*/}
public saveData(){
const {myData}=this.state;
const fileName=myData.name;
const json=JSON.stringify(myData);
const blob=new Blob([json],{type:'application/json'})
/* How to write/download this blob as a file? */
}
here trying window.navigator.msSaveOrOpenBlob(blob, 'export.json'); did not work
note: I know it has security risks, it is not for production. save the file in the project folder is preferred but a download is totally ok.
I had a blob containing data and I had found a solution on stackoverflow and manipulated a bit, and succeded to download as a xlsx file. I am adding my code below, it might help you, too.
const blob = await res.blob(); // blob just as yours
const href = await URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = href;
link.download = "file.xlsx";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
EDIT: You can use the function below, but be sure to switch out fileName and myData from this.state to something that will work in your application.
const downloadFile = () => {
const { myData } = this.state; // I am assuming that "this.state.myData"
// is an object and I wrote it to file as
// json
// create file in browser
const fileName = "my-file";
const json = JSON.stringify(myData, null, 2);
const blob = new Blob([json], { type: "application/json" });
const href = URL.createObjectURL(blob);
// create "a" HTLM element with href to file
const link = document.createElement("a");
link.href = href;
link.download = fileName + ".json";
document.body.appendChild(link);
link.click();
// clean up "a" element & remove ObjectURL
document.body.removeChild(link);
URL.revokeObjectURL(href);
}
More documentation for URL.createObjectURL is available on MDN. It's critical to release the object with URL.revokeObjectURL to prevent a memory leak. In the function above, since we've already downloaded the file, we can immediately revoke the object.
Each time you call createObjectURL(), a new object URL is created, even if you've already created one for the same object. Each of these must be released by calling URL.revokeObjectURL() when you no longer need them.
Browsers will release object URLs automatically when the document is unloaded; however, for optimal performance and memory usage, if there are safe times when you can explicitly unload them, you should do so.
For the ones like me here that are looking for an easier solution when you already have your JSON as a variable:
<button
href={`data:text/json;charset=utf-8,${encodeURIComponent(
JSON.stringify(YOURJSON)
)}`}
download="filename.json"
>
{`Download Json`}
</button>
<button
type="button"
href={`data:text/json;charset=utf-8,${encodeURIComponent(
JSON.stringify(YOURJSON)
)}`}
download="filename.json"
>
{`Download Json`}
</button>
if you are using the Loic V method just ad the type for the button on the button element and should work just fine.

Use javascript to generate a file to be downloaded. How to use the 'Save As' dialogue without HTTP headers?

I'm using this function to download a file:
function download(fileName, data) {
fileName = fileName.replace(/\s+/gi, '_').replace(/[^a-zA-Z0-9-.,_]/gi, '');
let blob = new Blob([data], {type: 'text/plain'});
if(window.navigator.msSaveOrOpenBlob){
window.navigator.msSaveBlob(blob, fileName);
}else{
let elem = window.document.createElement('a');
elem.href = window.URL.createObjectURL(blob);
elem.download = fileName;
document.body.appendChild(elem);
elem.click();
document.body.removeChild(elem);
}
}
// Example usage
$('button').on('click', function(){
download("test.txt", "test");
});
It works perfectly fine. However, it seems to download the file directly into the Downloads folder.
How can I make it open a 'Save As' dialogue instead, so the user can choose his preferred download location?
JSFiddle: https://jsfiddle.net/kbwrcL14/
I've seen suggestions before about manipulating the header like settiing a Content-Disposition -- however is that possible when you generate a file on-the-fly? Afaik headers are what is sent before the HTTP body, but by the time the JS code is running, the entire HTTP request has already finished, and the file is generated by the client itself.
Is there a way to make this work without using http headers?

Save a JSON file to server with javascript application

I'm developing a simple Javascript application where the user has some images (stored in my machine) and he is able to annotate them and then save the annotations as a JSON file.
The application is very light and simple and it is not an app server.
However, I need to save those JSON files to the machine that will be behaving as the server.
Since I cannot use Javascript for IO, is there any easy and simple way to save those files without having to implement an app server?
I used Blob to download the files.
function project_save_confirmed(input) {
if ( input.project_name.value !== _onco_settings.project.name ) {
project_set_name(input.project_name.value);
}
// onco project
var _onco_project = { '_onco_settings': _onco_settings,
'_onco_img_metadata': _onco_img_metadata,
'_onco_attributes': _onco_attributes };
var filename = input.project_name.value + '.json';
var data_blob = new Blob( [JSON.stringify(_onco_project)],
{type: 'text/json;charset=utf-8'});
save_data_to_local_file(data_blob, filename);
user_input_default_cancel_handler();
}
function save_data_to_local_file(data, filename) {
var a = document.createElement('a');
a.href = URL.createObjectURL(data);
a.download = filename;
a.click();
}
Any suggestion?
Kind regards!
Copy paste from: Download JSON object as a file from browser
function downloadObjectAsJson(exportObj, exportName){
var dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(exportObj));
var downloadAnchorNode = document.createElement('a');
downloadAnchorNode.setAttribute("href", dataStr);
downloadAnchorNode.setAttribute("download", exportName + ".json");
document.body.appendChild(downloadAnchorNode); // required for firefox
downloadAnchorNode.click();
downloadAnchorNode.remove();
}
This I believe accomplishes what you want, just makes sure that the proper headers are set, push it to an <a> tag, then click() it
You can do this in php:
<?php
//notice this will put WHATEVER is in json into file
$filename="config.json";
if (isset($_POST["json"])) {
file_put_contents($filename,$_POST["json"]);
}
?>
then for the JS side:
var fd=new FormData();
fd.append("json", JSON.stringify(_onco_project));
fetch("https://url.com",{method:"POST",body:fd})
Explanation: JS makes a new formdata, and sets "json" to the stringified json, and sends it off to the server. The php server takes this, and puts it directly into $filename. Make sure data is safe before putting it to file, as it will take whatever it is given and put it into your file!

Download/Save file in react js

How can i save the response from api which gives me excel file with data and name ?
I have below api which gives me the excel file and i have to save it at default location as is.
https://mydomain.dev.com/export
I have gone through the multiple articles on the web but everywhere its explained to save the data as excel file at client side which is not the my case. For me, file type and name is already decided at server side and i have to just save as is.
Thanks a lot in advance
Here's how I usually handle this:
I start out by fetching the file and then use downloadjs to download the blob
async downloadFile() {
const res = await fetch("https://mydomain.dev.com/export");
const blob = res.blob();
// from downloadjs it will download your file
download(blob, "file.xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
I always use this script to do this:
function downloadFile(absoluteUrl) {
var link = document.createElement('a');
link.href = absoluteUrl;
link.download = 'true';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
delete link;
};
So just :
downloadFile("https://mydomain.dev.com/export");
It is working, but i hope that there is better solution.

Categories