AngularJS read JSON from user upload - javascript

I would like to allow user upload a JSON file and assign the content of the JSON file to a $scope variable.
After the content of the file is been assigned to the scope variable, I want to totally discard the file itself and not storing it anywhere.
How to efficiently implement this function?

In your template:
<input type="file" onchange="angular.element(this).scope().onFileChange(this)">
In your JS:
$scope.onFileChange = function (fileEl) {
var files = fileEl.files;
var file = files[0];
var reader = new FileReader();
reader.onloadend = function(evt) {
if (evt.target.readyState === FileReader.DONE) {
$scope.$apply(function () {
$scope.something = JSON.parse(evt.target.result);
});
}
};
reader.readAsText(file);
};
"onchange" instead of "ng-change", because it looks like Angular doesn't support binding things with ng-change on file upload input controls.
This was stolen almost verbatim from a co-worker's code. It might be Chrome-specific. If someone who knows me sees this, all credit is due to this coworker. And it's all due to him in any event anyhow. ;)

Related

Upload and view an input file using VueJS

I am using TypeScript and Haml. I want to be able to upload and view a file using vue.js. I am able to upload an image but it is supposed to display it right away as demoed here: https://codepen.io/Atinux/pen/qOvawK/
Instead, I get this error:
http://localhost:8080/image Failed to load resource: the server responded with a status of 404 (Not Found)
If it's trying to get the image from the root directory, is my issue that I'm not saving it there? How would I solve this?
page_image.ts:
require("./page_image.scss");
import Vue = require("vue");
import {Injections} from "../../init";
export const PageImage = {
template: require("./page_image.haml"),
data: function () {
return {
image: ''
}
},
created() {
Injections.HeaderTextManager.setHeader("Videos");
Injections.HeaderTextManager.clearDescription();
},
methods: {
onFileChange(e:any) {
var files = e.target.files || e.dataTransfer.files;
if (!files.length)
return;
this.createImage(files[0]);
},
createImage(file:any) {
var image = new Image();
var reader = new FileReader();
var vm = this;
reader.onload = (e:any) => {
vm.image = e.target.result;
};
reader.readAsDataURL(file);
},
removeImage: function (e:any) {
this.image = '';
}
}
};
page_image.haml:
.page-image
.row
.col-xs-12
.box
.box-header
%div(v-if="!image")
%h3.box-title Upload an image
%input(type="file" v-on:change="onFileChange")
%div(v-else)
%img(src="image" name="image")
%img {{image}}
%button(v-on:click="removeImage") Remove image
I don't know haml, and I do not use typescript with vue.js. So I cannot give you a direct answer.
Here is a working jsFiddle example that implements FileReader with vue.js to provide an instant preview:
https://jsfiddle.net/mani04/5zyozvx8/
You may use the above for reference to debug your code.
Here is how it works: To make FileReader work properly, we need access to the DOM element for input. This can be accomplished as shown below:
<input type="file" #change="previewImage" accept="image/*">
The previewImage method gets the event parameter, which has event.target - the DOM element for input that we need. Now your previewImage method can read the image file normally as follows:
previewImage: function(event) {
// Reference to the DOM input element
var input = event.target;
// Ensure that you have a file before attempting to read it
if (input.files && input.files[0]) {
// create a new FileReader to read this image and convert to base64 format
var reader = new FileReader();
// and so on...
You may use this jsFiddle for reference, and keep this question open, so that others with knowledge of haml and typescript may provide a more direct answer.
I think the problem is caused because of this line in your page_image.haml
%img(src="image" name="image")
If it translates or compiles to <image src="image" name="image">, then your browser will look for image in localhost:8080/image instead of attempting to show from data.image inside Vue component.
As explained in my other answer, I dont know haml, so you have to figure out a way to fix it yourself.
Edit:
Looking at the other haml code in your question, does this work?
%img(v-bind:src="image" name="image")

Web Development Displaying Local Files

Based on research, I've found tutorials, such as this one from Eric Bidelman, that go into FileReader usage. Instead of local files, these tutorials use files provided by the user. Modifying these examples to try and display local files were not successful.
After some research I've found that most browsers by default do not allow access to local files [1]. Some recommend using unsafe modes for testing, but that's not what I'm looking for as that would apply to only my testing [2].
Currently I allow the download of log files. My goal here with FileReader was to provide a way to view the files as well. Is there a way to achieve this? I'm coming up with blanks and have almost resigned to only allowing downloads instead of adding viewing. The following is example code of local file reading. This code fails since 'logpath' is not of type blob. I believe my question doesn't really require code, but I provided an example anyway.
HTML Code
<select name="loglist" id="loglist" onchange="run()" size="2">
<option>stack1.log</option>
<option>stack2.log</option>
</select>
Javascript
function run() {
var reader = new FileReader();
log = document.getElementById( "loglist" ).value;
var logdir = "/var/log/";
var logpath = logdir.concat(log);
reader.onload = function() {
logtext = reader.result;
alert(logtext);
}
reader.readAsText(logpath);
}
There is no way for JavaScript, embedded in a webpage, to access files on the user's local system other than through the File API when the user selects the file using a file input. It is not possible for the page to supply the file name to be opened.
var inp = document.querySelector("input");
inp.addEventListener("change", show);
function show(e) {
var f = this.files[0];
var r = new FileReader();
r.addEventListener("load", display);
r.readAsText(f);
function display(e) {
document.body.appendChild(
document.createTextNode(
e.target.result
)
);
}
}
<input type="file" id="input">

HTML5 file upload script not loading file

Newbie to the HTML5 file upload capability, and finding I cant get a simple xml file uploaded and able to get file contents into console. The expected behaviour is that I'd select an xml file and then see the contents rendered in console. However, I dont ever get to the console.log step - seems the reader never loads? Any suggestions to resolve would be most appreciated.
<input type="file"></input>
<script>
var upload = document.getElementsByTagName('input')[0];
upload.onchange = function (e) {
e.preventDefault();
var file = upload.files[0], reader = new FileReader();
reader.onload = function (event) {
console.log('evt',reader.readAsText(file));
};
return false;
};
</script>
So you're setting the reader.onload event to a function, but you need to call the reader.readAsText() function outside of this.
So for example change your code to:
reader.onload = function(event) {
console.log(event);
};
reader.readAsText(file);
What this does is to tell the reader that when you call reader.readAsText(file) it should run the function you defined with reader.onload.
What you were doing before would never load the file because you were only telling the reader to readAsText inside your function callback that you told it to run when it was already loaded!

How do i remove files from a zip file uploaded through kendoUpload? Using jszip

After the user uploads a zipped file, i want to remove the images folder from it before sending it over the network. I am using kendo for uploading, and the existing functionality works fine. I just want to add on the removing images part. This is what i have so far:
function onSelect(e) {
var file = e.files[0];
if (endsWith(file.name, '.eds')) {
var contents = e.target.result;
var jszip = new JSZip(contents);
jszip.remove("apldbio/sds/images_barcode");
fileToSend = jszip.generate({type: "base64", compression: "DEFLATE"});
}
e.files[0] = fileToSend;
openProgressDialog(e.files.length); //this is existing code, works fine
}
target.result doesn't seem to exist in the event e. And nothing works properly from that point on. e should probably be used inside a FileReader object's onload(), (as seen here and here) but i have no idea how to use a FileReader for my purpose, with kendo Upload.
EDIT:I did some more reading and now i am using FileReader like this:
var reader = new FileReader();
reader.onload = function (e) {
// do the jszip stuff here with e.target.result
};
reader.onerror = function (e) {
console.error(e);
};
reader.readAsArrayBuffer(file);
Note : file = e.files[0] as in the 1st code block.
With this though, i get the error:
Failed to execute 'readAsArrayBuffer' on 'FileReader': parameter 1 is not of type 'Blob'.

How to get all sliced data from the entire file

I get the original code from here: Using Javascript FileReader with huge files
But my purpose is different, the author wants to get just a part of the whole but I want them all.
I'm trying modify it with loop, mixed with this technique: slice large file into chunks and upload using ajax and html5 FileReader
All fails, is there anyway I can get what I want.
var getSource = function(file) {
var reader = new FileReader();
reader.onload = function(e) {
if (e.target.readyState == FileReader.DONE) {
process(e.target.result);
}
};
var part = file.slice(0, 1024*1024);
reader.readAsBinaryString(part);
};
function process(data) {
// data processes here
}
Thank you,

Categories

Resources