Reading JSON file in angular 2 application - html

I have a file data.json which I want to import in my angular 2 application. I am getting file with HTML input tag.
<input type="file" (change)="onImport($event)"/>
in my typescript file I want to read this data.json file and store the content of file in JSON array. I have searched but couldn't find any way to read file or any library which could help me with this.

Use FileReader from the File API and JSON.parse() method like:
onImport(event) {
var file = event.srcElement.files[0];
if (file) {
var reader = new FileReader();
reader.readAsText(file, "UTF-8");
reader.onload = function (evt) {
console.log(JSON.parse(evt.target.result));
}
reader.onerror = function (evt) {
console.log('error reading file');
}
}
}

I tried to apply #Stanislav solution but faced few issues. Eventually the following code worked
Ref: get the value from a FileReader in Angular 2
html code
<input (change)=readJson($event);" type="file" />
component.ts code
readJson(event) {
var file = event.srcElement.files[0];
if (file) {
var reader = new FileReader();
reader.readAsText(file, "UTF-8");
reader.onload = function (evt) {
console.log(JSON.parse(evt.target["result"]));
}
reader.onerror = function (evt) {
console.log('error reading file');
}
}
}
event.target["result"] is the part I modified.

Related

I want to upload a file as byte array from angular to wepapi

I am new to angular. Actually I want to upload a file as a byte array from "angular" to "wepapi"
I can find the codes to upload file from "angular" to "wepapi"
like below code
onFileSelected(event) {
const file:File = event.target.files[0];
if (file) {
this.fileName = file.name;
const formData = new FormData();
formData.append("thumbnail", file);
const upload$ = this.http.post("/api/thumbnail-upload", formData);
upload$.subscribe();
}
}
How can I sent a file as a "byte" array instead of "formData"
Kindly suggest some ideas.

How to load file after being uploaded (not saved in database yet) in angular, html

I have a file upload control in my angular app where user could upload any type of file except a few ones .exe, .sql etc
<input type="file" id="file" #file (change)="fileUploadHandler($event)" multiple>
fileupload.component.ts
fileUploadHandler(event: Event) {
const inputElement = event.target as HTMLInputElement;
if (inputElement.files && inputElement.files?.length) {
_each(inputElement.files, (_file) => {
const fileSize = _file.size;
if (fileSize < this.MAX_DOC_SIZE) {
const fileName = _file.name?.trim();
const doc = new Document();
doc.name = fileName;
doc.extension = fileName.slice(fileName.lastIndexOf('.') + 1);
doc.size = fileSize;
this.docs.push(doc);
}
});
}}
This list the files in UI as below
Now what I need is that when user click on a file, that file should open in a new tab
how can I do this?
On googling I see suggestions to use FileReader & gave a try
_each(inputElement.files, (_file) => {
const reader = new FileReader();
const data = reader.readAsDataURL(_file);
console.log(data) // nothing is printed on console
Please suggest. Thanks!
You have to enhance the code a little bit (as #mav-raj also stated). In Angular you can use the following:
_each(inputElement.files, (_file) => {
const reader = new FileReader();
reader.onloadend = ((result) => {
console.log(result) // now something will be printed!
});
reader.readAsDataURL(_file);
})

Excel to JSON parsing

I am trying to parse Excel data to JSON to feed drop downs in HTML. I am having a hard time getting this to work. I have looked all over the web. I am new to javascript so i find it overwhelming.
There seems to be a lot of scripting and to make this work. If anyone can help and explain how to set this up i would be greatly appreciative.
Thanks All,
HAppleknocker
This article explained clearly how to make the JSON object from a Excel File. After getting the JSON object as a string you can use it to do anything.
In here used sheet js and sample javaScript code available on GitHub.
How to convert Excel data into JSON object using JavaScript
<script>
$(document).ready(function(){
$("#fileUploader").change(function(evt){
var selectedFile = evt.target.files[0]; //Get the ExcelFile
var reader = new FileReader();
reader.onload = function(event) {
var data = event.target.result;
var workbook = XLSX.read(data, {
type: 'binary'
});
workbook.SheetNames.forEach(function(sheetName) {
var XL_row_object = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
var json_object = JSON.stringify(XL_row_object);
document.getElementById("jsonObject").innerHTML = json_object;
})
};
reader.onerror = function(event) {
console.error("File could not be read! Code " + event.target.error.code);
};
reader.readAsBinaryString(selectedFile);
});
});
</script>

Change other file inside EventStream of other gulp

I have one interesting question. Is it possible to change some file inside open stream (EventStream) inside gulp?
I have that stuff. I want to read some file inside opened stream and write that stuff to other file. How I can do it? Thanks.
gulp.task('handleGlobalStorage', function () {
return gulp.src('./global_storage.js')
.pipe(setEnvHostAndProxy())
.pipe(gulp.dest('./built'));
});
function setEnvHostAndProxy() {
return es.map(function(file, cb) {
var fileContent = file.contents.toString();
//some changes inside content
// if (!gutil.env.dev) return;
/* I have stuff that fetched from file and I modify it that I send it
down to pipe. But also I want to insert this stuff inside other
file. How I can do it? Should I create WritableStream of that file
and merge it ?*/
file.contents = new Buffer(fileContent);
// send the updated file down the pipe
cb(null, file);
});
}
I resolved that issue, here is solution (I will not show all code, only general). The main concept is - open file and write new stuff inside pipe :) that's all.
function setEnvHostAndProxy() {
var bsConfigFileContent = fs.readFileSync('./bs-config.js', 'utf8'),
bsConfigProxyPattern = /(proxyUrl\s?=\s?)["|'](.*)["|']/;
return es.map(function (file, cb) {
var fileContent = file.contents.toString(),
prodHost = fileContent.match(generateRegExpForHosts('prodHost'))[1],
prodProxy = fileContent.match(generateRegExpForHosts('prodProxy'))[1],
devProxy = fileContent.match(generateRegExpForHosts('devProxy'))[1],
devHost = fileContent.match(generateRegExpForHosts('devHost'))[1],
changedBsConfigFileStream,
res;
if (!gutil.env.dev) {
res = prodHandler();
changedBsConfigFileStream = bsConfigHandler(prodHost);
} else {
res = devHandler();
changedBsConfigFileStream = bsConfigHandler(devProxy);
}
fs.writeFile('./bs-config.js', changedBsConfigFileStream, 'utf8', function (err) {
if (err) throw (err);
});
file.contents = new Buffer(res);
cb(null, file);
} });

In HTML5 is there any way to make Filereader's readAsBinaryString() synchronous

How to wait till onload event completes
function(){
var filedata=null;
reader.onload=function(e){
filedata=e.target.result;
};
reader.readAsBinaryString(file);
//I need code to wait till onload event handler gets completed.
return filedata;
}
Typical solution to this is to separate your code so, that the part which uses the loaded data is in a separate function, which is then called from the event.
Pseudo-code'ish:
function load() {
//load here
reader.onload = function(e) {
process(e.target.result);
}
}
function process(result) {
//finish working here
}
You can read synchronously using threads (Webworkers in Javascript).
http://www.w3.org/TR/FileAPI/#readingOnThreads
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.0.min.js"></script>
<form><input type="file" id="files" name="file" onchange="upload()" /></form>
function readFile(dfd) {
bytes = [];
var files = document.getElementById('files').files;
if (!files.length) {
alert('Please select a file!');
return;
}
var file = files[0];
var reader = new FileReader();
// If we use onloadend, we need to check the readyState.
reader.onloadend = function(evt) {
if (evt.target.readyState == FileReader.DONE) { // DONE == 2
var content = evt.target.result;
//bytes = stringToBytes(content);
dfd.resolve(content);
}
};
reader.readAsBinaryString(file);
}
function upload() {
var dfd = new $.Deferred();
readFile(dfd);
dfd.done(function(content){
alert("content:" + content);
});
}
The answer by Jani is correct, but in the case of dropping multiple files at once in a droparea, there are not separate events for each file (as far as I know). But the idea may be used to load the files synchronously by recursion.
In the code below I load at number of files and concatenate their content into a single string for further proccesing.
var txt="", files=[];
function FileSelectHandler(e) {
e.preventDefault();
files = e.target.files || e.dataTransfer.files;
txt="";
readFile(0);
}
function readFile(n) {
file=files[n];
var reader = new FileReader();
reader.onload = function() {
txt += reader.result;
}
reader.readAsText(file);
if (n<files.length-1) { readFile(n+1); }
else { setTimeout(doWhatEver, 100);}
}
function doWhatEver(){
outtext.innerHTML=txt;
}
The last file also needs a bit of extra time to load. Hence the "setTimeout".
"outtext" is the handle to a textarea where the entire string is displayed. When outputting in at textarea the browser wont' parse the string. This makes it possible to view not only text but also html, xml etc.
No there is not. All IO operations must be asynchronous in Javascript.
Making file operation synchronous would effectively block the browser UI thread freezing the browser. The users don't like that.
Instead you need to design your script in asynchronous manner. It is quite easy with Javascript.