Javascript: Filereader onloadend with TypeError - javascript

Actually I tried to read a file in ionic 2 using a filereader object. But instead of firing the onloadend function I can see all my wanted data in the console by adding the whole reader into the output, but I'm not able to get this data.
Here's my code:
loadFile(path) {
this.platform.ready().then(() => {
window.resolveLocalFileSystemURL(path, gotFile, fail);
function fail() {
console.log('fail()');
}
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(evt) {
console.log('onload');
}
reader.readAsText(file);
console.log(reader);
})
}
});
In the console I can see under onloadend inside the caller object under arguments and under caller the following message:
Exception: TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context. at Function.remoteFunction (:3:14) at Object.InjectedScript.callFunctionOn (:724:66)
How can I fix this problem? Thanks in advance!

Related

Blazor WebbAssembly exception when calling javascript function?

I have a C# function that is invoking a Javascript function, this is the C# function:
await _jsRuntime.InvokeVoidAsync("setMediaUsingStreaming", type, dotnetImageStream);
And this is the Javascript function:
async function setMediaUsingStreaming(fileType, fileStream) {
try {
const arrayBuffer = await fileStream.arrayBuffer();
const blob = new Blob([arrayBuffer]);
const url = URL.createObjectURL(blob);
var newHTMLElement;
var fileHTMLElement = document.getElementById('fileDisplay');
if (fileType == "image") {
newHTMLElement = document.createElement('img');
}
else {
newHTMLElement = document.createElement('video');
var attribute = document.createAttribute('controls');
newHTMLElement.setAttributeNode(attribute);
}
fileHTMLElement.appendChild(newHTMLElement);
newHTMLElement.src = url;
} catch (Exception)
{
console.log(Exception)
}
}
When the C# function is invoking the Javascript function I receive this error :
blazor.webassembly.js:1 Uncaught (in promise) Error:
Microsoft.JSInterop.JSException: Cannot set properties of null
(setting 'src') TypeError: Cannot set properties of null (setting
'src')
The weird thing is that I receive this error when I run the app in publish mode (withouth a debugger) but it works perfectly in debug mode. The catch from the javascript function is not hit when I receive this error, it seems that is the C# method that is throwing it.
I know what the error is saying, that the url variable is null, but I don't understand why is null, and why it works on debug mode.
Do you have any ideas ?

Parsing error in a FileReader onload function

For some reason I am getting an error with my FileReader unload function. The error is Parsing error: Invalid left-hand side in assignment expression I looked in to what that means to according to MDN web docs: "invalid assignment left-hand side" occurs when there was an unexpected assignment somewhere. For example, a single "=" sign was used instead of "==" or "===". I don't see how this would be a error.
var fileInput = files[0];
var audioCtx = new AudioContext(files[0]);
var reader1 = new FileReader();
reader1.onload() = function (ev) { //error here
//decode audio
audioCtx.decodeAudioData(ev.target.result).then(function(buffer) {
reader1.readAsArrayBuffer(fileInput.files[0]);
})
}
onload is a property, not a method.
reader1.onload = function (ev) {
...
}

WKWebView web worker throws error "Dom Exception 18 returns an error."

I am writing an app using PhoneGap. I want to use javascript Web Worker. It works fine on Android. It also works on iOS with UIWebView.
I would like to use WKWebView in iOS 9. I tried to read the .txt files in a local folder successfully using cordova-plugin-file.
I have used the following tutorial:
https://www.scirra.com/blog/ashley/25/hacking-something-useful-out-of-wkwebview
But this did not solve it...
new Worker ('js/tested.js');
Dom Exception 18 returns an error.
new Worker ('www/js/tested.js');
Dom Exception 18 returns an error.
I tried to specify the full path to worker javascript file, but I get the same error:
new Worker (file_path+'js/tested.js');
Dom Exception 18 returns an error.
So how to create the worker?
It worked!
Web workers without a separate Javascript file?
var worker_js = null;
function fetchLocalFileViaCordova(filename, successCallback, errorCallback)
{
var path = cordova.file.applicationDirectory + "www/" + filename;
window.resolveLocalFileSystemURL(path, function (entry)
{
entry.file(successCallback, errorCallback);
}, errorCallback);
};
function fetchLocalFileViaCordovaAsText(filename, successCallback, errorCallback)
{
fetchLocalFileViaCordova(filename, function (file)
{
var reader = new FileReader();
reader.onload = function (e)
{
successCallback(e.target.result);
};
reader.onerror = errorCallback;
reader.readAsText(file);
}, errorCallback);
};
fetchLocalFileViaCordovaAsText("js/worker.js", function (js_script) { // Worker WKWebView
worker_js = window.URL.createObjectURL(
new Blob([js_script], { type: "text/javascript" })
);
});
if (worker_js != null) {
backgroundEngine = new Worker(worker_js);
} else {
backgroundEngine = new Worker("js/worker.js");
}

Why am I receiving ReferrenceError: BinaryFile is not Defined

I'm following the result in this answer exactly but I am receiving the following error:
ReferenceError: BinaryFile is not defined
Here's the code where that is used:
fr.onloadend = function() {
console.log(this);
exif = EXIF.readFromBinaryFile(new BinaryFile(this.result));
}
The console.log shows that there is data there, I just don't understand this error I'm receiving.
Thank you for your help.
I used the following which worked very well
EXIF.getData(img, function() {
orientation = EXIF.getTag(this, "Orientation");
});
where img is my image object.
Also EXIF.pretty(this) was helpful to see what data is in each image.
Removing BinaryFile and changing how FileReader read the file (readAsArrayBuffer) worked for me.
fileReader.onload = function (event) {
var exif = fileReader.readFromBinaryFile(this.result);
console.log(exif);
};
fileReader.readAsArrayBuffer(file);

Passing file contents to outside variable

I'm using a FileReader and the HTML file dialog to read a file in my script. How do I pass this file's contents out of the FileReader.onload function?
function readFileData(evt) {
var file = evt.target.files[0];
var reader = new FileReader();
reader.onload = function(e) {
var contents = e.target.result;
}
reader.readAsText(file);
}
document.getElementById('file').addEventListener
('change', readFileData, false);
/* I want to access the contents here */
I tried sticking returns in the readFileData and onload functions, but I'm not sure what they return to.
I assume that you know, its async and all.
So, the short answer is: No, you can not do that.
However, if you want the contents to be globally accessible for any future calls, you could something like this:-
var contents;// declared `contents` outside
function readFileData(evt) {
var file = evt.target.files[0];
var reader = new FileReader();
reader.onload = function(e) {
contents = e.target.result; //<-- I removed the `var` keyword
}
reader.readAsText(file);
}
document.getElementById('file').addEventListener('change', readFileData, false);
var reasonableTimeToWaitForFileToLoad = 100000;
console.log(contents); //`contents` access first attempt: prints undefined
setTimeout(function() {
console.log(contents);//`contents` access second attempt: prints the contents 'may be if the time allows.'
}, reasonableTimeToWaitForFileToLoad);
var contents;
function readFileData(evt) {
var file = evt.target.files[0];
var reader = new FileReader();
reader.onload = function(e) {
contents = e.target.result;
}
reader.readAsText(file);
reader.onloadend=function(e) {
console.log(contents)
}
}
document.getElementById('file').addEventListener('change', readFileData, false);
This is a scoping issue. When you're declaring contents within the onload, it's no longer available after that function has run. You need to declare contents outside of that scope first.
var contents;
function readFileData(evt) {
var file = evt.target.files[0];
var reader = new FileReader();
reader.onload = function(e) {
contents = e.target.result;
}
reader.readAsText(file);
}
document.getElementById('file').addEventListener
('change', readFileData, false);
//make changes here
//contents should have the correct value
Firstly, you have to realize that reading a file with a FileReader is an asynchronous task, and you cannot work with it in a synchronous manner.
There are many ways to handle this, but many of them are not suited for recommendations ;)
I would do it one of these 2 ways:
1: you can call a function from within the onload event handler and pass the file contents as a parameter
2: you can trigger an event from within the onload event handler and pass the file contents as event data
Just declare contents outside both functions and assign to it inside the inner function:
var contents;
var outer_fn = function() {
var inner_fn = function() {
contents = '42';
}
inner_fn();
}
outer_fn();
// here, `contents' is '42'
I faced a similar challenge and this is what I used to solve the issue.
var contents;
function readFileData(evt) {
var file = evt.target.files[0];
var reader = new FileReader();
reader.onload = function(e) {
contents = e.target.result;
}
reader.readAsText(file);
//calling to access the 'contents' variable
accessFileContents();
}
document.getElementById('file').addEventListener('change', readFileData, false);
var wait4file2load = 1000;
/* To access 'contents' here */
function accessFileContents(){
setTimeout(function(){
console.log(contents);
}, wait4file2load);
}
It won't give undefined value since we are calling it after the file is completely uploaded.
I had a similar problem in Angular 7 (typescript), and this is how I solved my problem.
What I wanted to do was to access the base64 conversion that was happening inside fileReader -> reader.onload
Then pass that parameter to another method where I could convert it to a JSON object then post it to the API seeing I want to post another parameter as well in the post. (not added in this code)
What I did first was to declare what I potentially needed to access outside the Method that.
base: any = null;
base64File: any = null;
fileToTest: any = null;
Then I converted the pdf to base64 when the upload event fired
convertToBase64 (e){
this.fileToTest = e.target.files[0];
var reader = new FileReader();
reader.onload = () => {
this.base64File = reader.result.slice(28);
};
reader.onerror = function (error) {
console.log('Error: ', error);
}.bind(this.base64File);
reader.readAsDataURL(this.fileToTest);
return this.base64File;
}
Finally access the base64 file in the other method
onSubmit() {
console.log("base 64 file is visible", this.base64File);
var base =
{
"FileBase64": this.base64File,
"Path": "document",
"FileType": ".pdf"
};
console.log("JSON object visible", base);
this.uploadService.base64Post(base);
}
Everything works now, and hopefully maybe this can help someone else finding themselves with the same problem.
Using Angular 7, code is in the component file, and the post function is in the Service file. Without my comments the code is exactly like this in the component file.

Categories

Resources