How to save data with pwa - javascript

I am working on my own project where I want to create an application, which runs on android and iOS. I decide using HTML, CSS and JavaScript for creating a PWA. The app should enable the user to manage recips for tart incl. Cost calculation. My problem is, that I want to save the recips/ingredients in form of a table. The data should be stored permanently locally on the device. With the method "localstorage" the data are only saved temporarily. I don't want to host a webserver/database. The data should not be lost when the user delete the local cache of the browser.
Is it possible to store general data with java script, for example in a text file, outside of the browser's cache?

In your case indexedDB would be my go to solution. It can be deleted by a user as all data stored in the browser. Browser can't store data in text files (at least as per October 2021)

It is possible. but it's not straightforward it must be done manually by the user.
You can generate your DB as a downloadable file -eg. .txt or .csv- and provide the download link for the user or just auto-download it.
here's an example.
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.
document.getElementById("dwn-btn").addEventListener("click", function(){
// Start the download of yournewfile.txt file with the content from the text area
var text = document.getElementById("text-val").value;
var filename = "yournewfile.txt";
download(filename, text);
}, false);
to load the data you can create an import button that receives the data and populates the table.
here's how you can read file data
function readImage(file) {
// Check if the file is text.
if (file.type && !file.type.startsWith('text/')) {
console.log('File is not an textfile.', file.type, file);
return;
}
const reader = new FileReader();
reader.addEventListener('load', (event) => {
img.src = event.target.result;
});
reader.readAsDataURL(file);
}
I recommend using this approach with indexedDb or local storage.

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

Javascript - Print Blob Content Returned from API

I'm building a page for my angular2 web application where a user can select customers from a list and print off letters to mail them. These letters were uploaded as PDFs and are stored as varbinary in the database.
In the case of multiple selections, I'm simply appending byte[]'s so the user will print one document containing all of the letters to send to customers.
I'm able to pull the blob successfully from the API and return it with the content type application-pdf but then I don't know what to do with it from there.
Here's my Angular2 Component API Call:
this.printQueueService.getPrintContent(printRequests) //customers to receive letters
.subscribe((data: Blob) => {
var element: HTMLIFrameElement = <HTMLIFrameElement>document.getElementById('printFile');
element.innerText = data + ""; //what do I do with the blob?
element.contentWindow.print();
});
HTML Element:
<iframe id="printFile" style="display:none"></iframe>
I know I can just download the PDF and prompt the user to print using a PDF Viewer, but I'd rather not force users to go through extra steps.
I'd also rather not try to render the PDF in the browser and print because it assumes users have the proper plugins and browsers support it.
What options do I have for printing a blob in the browser?
As per suggestions from Daniel A. White, I solved this issue. I decided not to use an IFrame because these print files could be massive and the print() function includes the page name as footnotes.
Instead, I chose to open the generated PDF in a new tab as follows:
if (window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(data, "PrintedLetters.pdf"); //IE is the worst!!!
}
else {
var fileURL = URL.createObjectURL(data);
var a: HTMLAnchorElement = document.createElement('a');
a.href = fileURL;
a.target = '_blank';
document.body.appendChild(a);
a.click();
}

extension crash on exporting stringified/encodeURIComponent data to file

It is about exporting extension data from options page.
I have array of objects, with stored page screenshots encoded in base64, and some other minor obj properties. I'm trying to export them with this code:
exp.onclick = expData;
function expData() {
chrome.storage.local.get('extData', function (result) {
var dataToSave = result.extData;
var strSt = JSON.stringify(dataToSave);
downloadFn('extData.txt', strSt);
});
}
function downloadFn(filename, text) {
var fLink = document.createElement('a');
fLink .setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
fLink .setAttribute('download', filename);
fLink .click();
}
On button click, get data from storage, stringify it, create fake link, set attributes and click it.
Code works fine if resulting file is under ~1.7 MB, but everything above that produce option page to crash and extension gets disabled.
I can console.log(strSt) after JSON.stringify and everything works fine no matter of the size, if I don't pass it to download function..
Is there anything I can do to fix the code and avoid crash?...or is there any limitation is size when using this methods?
I solved this, as Xan suggested, switching to chrome.downloads (it's extra permission, but works fine)
What I did is just replacing code in downloadFN function, it's cleaner that way
function downloadFn(filename, text) {
var eucTxt = encodeURIComponent(text);
chrome.downloads.download({'url': 'data:text/plain;charset=utf-8,'+eucTxt, 'saveAs': false, 'filename': filename});
}
note that using URL.createObjectURL(new Blob([ text ])) also produce same crashing of extension
EDIT:
as #dandavis pointed (and RobW confirmed), converting to Blob also works
(I had messed code that was producing crash)
This is a better way of saving data locally, because on browser internal downloads page, dataURL downloads can clutter page and if file is too big (long URL), it crashes browser. They are presented as actual URLs (which is raw saved data) while blob downloads are only with id
function downloadFn(filename, text) {
var vLink = document.createElement('a'),
vBlob = new Blob([text], {type: "octet/stream"}),
vUrl = window.URL.createObjectURL(vBlob);
vLink.setAttribute('href', vUrl);
vLink.setAttribute('download', filename);
vLink.click();
}

Let the User download the CSS file for iframe element

I am using two following JS functions to do the following steps:
Get iFrame html content generated via user interaction into a string
THEN Get the CSS stylesheet contained on my server named "myStylesheet.css" into a string
THEN Download those files to the reguesting user
var iframe = document.getElementById('frame');
function downloadFile(filename, text) {
var pom = document.createElement('a');
pom.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
pom.setAttribute('download', filename);
if (document.createEvent) {
var event = document.createEvent('MouseEvents');
event.initEvent('click', true, true);
pom.dispatchEvent(event);
}
else {
pom.click();
}
//example : downloadFile("hello.txt", "Hello World!") or for custom name filedownloadFile(myPageName +'.html', iFrameContent)
}
function publishWebsite(){
var htmlCodeForFrame = document.getElementById('frame').contentWindow.document.body.innerHTML;
var ccsCodeForFrame = "";
downloadFile("myWebsite.html", htmlCodeForFrame); //save html of frame into a file and download it to user
downloadFile("myStylesheet.css", ccsCodeForFrame); //save css of frame into a file and download it to user
}
My problem lies in turning a CSS stylesheet into a variable then download it (I want to stick with my download function for clarity because this is a Team Project and it's used in many other places.) to user. I wish this to be done in Javascript.
For modern browsers you could use the download-tag
Download
N.B: the file name is not required
(see browser support)
One other (rather nasty) trick is to create an ajax request with an invalid MIME-type, this prompts the browser to download the file since it can't render the view. Or you could use the application/octet-stream MIME-type.
I found myself using the following after some tinkering:
<iframe id="cssFrame" src="myStylesheet.css" style="display: none;"></iframe>
With conjunction of my code from the first post, I saved the content of the iframe to a string and saved the string in a file with .css extension. Works good.

Create a text file using client side code

Is there a way to create a text file (and write some JSON data to it ) using client side code only (no server-side code / web services )?
You can use local storage to store data client-side, but there is no way to do this server-side.
My best guess would be that you need to use javascript localstorage to store json.
example :
var myObject = {};
localstorage['myKey'] = myObject;
var secObject = localstorage['mykey'];
//you couls also use :
localstorage.setItem('myKey', myObject);
secObject = localstorge.getItem('myKey');
I usually "stringify" my JSON before saving it in case i need to modify "myObject" after saving it (because when you copy an object you actually copy a reference to it)
localstorage['myKey'] = JSON.stringify(myObject);
secObject = JSON.parse(localstorage['myKey']);
How are you all missing his point? You are able to generate text files and .csv files on client side and deliver it as a download.
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 :)");
From this link:
https://ourcodeworld.com/articles/read/189/how-to-create-a-file-and-generate-a-download-with-javascript-in-the-browser-without-a-server

Categories