Reputation: 1325
I'm trying to write data to a json file after hitting "Submit" on an html formly-form using only angular, but nothing is happening. I know I can read a json file using angular but not sure on creating files. onSubmit() in controller:
function onSubmit() {
$scope.save = function() {
$http.post('./temp/sample_data.json', JSON.stringify($scope.model)).then(function(data) {
$scope.msg = 'Data saved';
});
};
};
html:
<form name="form" ng-submit="onSubmit()" novalidate>
<formly-form model="model" fields="fields"></formly-form><br/>
<button type="submit">Submit</button>
</form>
The sample_data.json isn't created and if I create an empty file it does not fill up with the data as well. The $scope.model defenitly contains data. If anyone can help, it will be very appreciated. Thanks, Alon.
Upvotes: 37
Views: 87130
Reputation: 83
Ok, I'm digging in the past here, but the question is still relevant, judging by me looking for it today.
The accepted answer is the right one, I just want to add this implementation that works in Angular 15, from within a button click handler, without adding an actual element to the DOM and also sets the name of the file for download. It's dealing with a .csv file, but it is the same for .json too.
onExportButtonClick() {
// Render the CSV file content
let textResult = 'column1,column2,column3\n';
textResult += ... generate text content ...
// Create a blob from the CSV file content
const blob = new Blob([textResult], { type: 'text/csv' });
// Create a link to the blob
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = 'generated_filename.csv';
link.click();
}
And in the template (with Angular Material):
<button mat-raised-button
color="primary" (click)="onExportButtonClick()">
<mat-icon>save_alt</mat-icon>
Export
</button>
Clicking on this button initiates a download of the generated file.
Upvotes: 1
Reputation: 1998
The following code adds a download button for a JSON object.
Note: wrapping a button with an anchor tag is not recommended for HTML 5 yet it works in Chrome which is all I needed. YMMV.
HTML:
<a download="my-json-object.json" [href]="dataUri">
<button>Download</button>
</a>
Typescript:
get dataUri(): SafeUrl {
const jsonData = JSON.stringify(this.dataSource);
const uri = 'data:application/json;charset=UTF-8,' + encodeURIComponent(jsonData);
return this.sanitizer.bypassSecurityTrustUrl(uri);
}
Upvotes: 1
Reputation: 1075337
Is it possible to write data to a locally json file with nothing but angular?
No. Even if you're running the page from the local file system (e.g., file://myfile.html
) or from a local webserver (e.g., http://localhost/myfile.html
or http://host-on-my-intranet/myfile.html
), you still have no means of directly writing to a file from browser-hosted JavaScript code.
Two choices:
Send it to something (e.g., a server) that can write it out, or
Provide it as a data:
URI (if feasible in your case) that the user can right-click and choose "save as..."
Here's how you create a data:
URI for some JSON text:
var uri = "data:application/json;charset=UTF-8," + encodeURIComponent(theJSON);
Full Example of #2:
var theData = {
foo: "bar"
};
var theJSON = JSON.stringify(theData);
var uri = "data:application/json;charset=UTF-8," + encodeURIComponent(theJSON);
var a = document.createElement('a');
a.href = uri;
a.innerHTML = "Right-click and choose 'save as...'";
document.body.appendChild(a);
Upvotes: 38
Reputation: 26096
Since this is not possible you could try another route. Your $scope.save was not being invoked by the way, only assigned.
$scope.save = function() {
localStorage.model = JSON.stringify($scope.model);
};
function onSubmit() {
$scope.save();
$scope.msg = 'saved';
};
To get your model back do this on init:
if (localStorage.model)
$scope.model = JSON.parse(localStorage.model);
Upvotes: 3
Reputation: 17952
You can't access the local filesystem (directly) from Javascript. This is enforced for security reasons (and makes sense when you think about it!).
Local file access with javascript
Upvotes: 5
Reputation: 944217
No.
Angular runs client side.
If you want to write data to the server (even one on the same computer as the browser) then you need server side code to do it.
Upvotes: 5