Reputation: 9065
I am trying read a image file selected by a input[type=file]
field with this javascript code:
var reader = new FileReader();
var blob;
reader.onloadend = function (e) {
blob = e.target.result;
}
reader.readAsDataURL(this.files[0]);
but when I run the code in the browser, I am getting this error:
TypeError: Argument 1 of FileReader.readAsDataURL is not an object.
Anyone can see what's wrong here?
UPDATE
this is the code where this snippet is included. SHould given more context about what's causing the error, I hope:
$('#submit').on('click', function(){
var $form = $( 'form.form' ), url = $form.attr( "action" ), str = $form.serialize();
$('input[type=file]').each(function(){
var reader = new FileReader();
var blob;
reader.onloadend = function (e) {
blob = e.target.result;
}
reader.readAsDataURL(this.files[0]);
str = str + "\u0026" + $(this).attr("name") + "=" + blob;
});
var posting = $.post( url, str );
posting.done(function(data){
if(data == "") {
$("#alerta_sucesso").css("display", "block");
} else {
$("#alerta_erro").find("#texto").text(data);
$("#alerta_erro").css("display", "block");
}
});
});
UPDATE 2
I manage to change the code and execute it without errors, but even so I can't store the image inside the variable blob
to send this data to the server. The curretn code is this:
$('#submit').on('click', function(){
var $form = $( 'form.form' ), url = $form.attr( "action" ), str = $form.serialize();
var input = $form.find('input[type=file]');
$form.find('input[type=file]').each(function(){
var id = $(this).attr("id");
if(typeof id !== "undefined") {
if(this.files.length > 0) {
var reader = new FileReader();
var blob;
reader.onloadend = function (e) {
blob = e.result;
}
reader.readAsDataURL(this.files[0]);
str = str + "\u0026" + $(this).attr("name") + "=" + blob;
}
}
});
var posting = $.post( url, str );
posting.done(function(data){
if(data == "") {
$("#alerta_sucesso").css("display", "block");
} else {
$("#alerta_erro").find("#texto").text(data);
$("#alerta_erro").css("display", "block");
}
});
});
I assume the problem now it's with the line:
blob = e.result;
Anyone knows what should be the right value for this?
Upvotes: 2
Views: 7459
Reputation: 9065
So, I finally manage to solve this issue with this approach:
var str = "";
$('input[type=file]').on("change", function(){
var id = $(this).attr("id");
var name = $(this).attr("name");
if(typeof id !== "undefined") {
if(this.files.length > 0) {
reader = new FileReader();
reader.onloadend = function () {
str += "&" + name + "=" + this.result;
}
reader.readAsDataURL(this.files[0]);
}
}
});
$('#submit').on('click', function(){
var $form = $( 'form.form' );
var url = $form.attr( "action" );
str += $form.serialize();
$.post(url, str, function(data){
if(data == "") {
$("#alerta_sucesso").css("display", "block");
} else {
$("#alerta_erro").find("#texto").text(data);
$("#alerta_erro").css("display", "block");
}
});
});
and now the image is being sent to server as a string which can be handled by the PropertyEditorSupport class; this is the thing I am trying make work right now.
Upvotes: 0
Reputation:
FileReader is asynchronous and the execution happens in a singular thread.
This means when this line is called (I can't see str
being defined anywhere, if not, remember to set it to an initial string before appending it, ie. var str = "";
):
str = str + "\u0026" + $(this).attr("name") + "=" + blob;
blob
is not yet filled with any value yet as it need to wait for the entire function block to finish execution so the code inside the handler can be executed.
You need to build the resulting string from within the callback:
var reader = new FileReader();
reader.onloadend = function() {
str += "&" + $(this).attr("name") + "=" + this.result;
// continue from here ...
};
reader.readAsDataURL(this.files[0]);
But blob
is not a blob in this code (or this.result
after my changes above), it's a string holding a data-uri at this point. You may need to encode your string first if this is intended to be part of a URI argument (see for example encodeURIComponent - with images as data-uri you may also run into length limitations and will have to use POST).
If you need an actual blob you don't even need to use FileReader - simply use the file object which is also a blob (from this.files[n]
).
Upvotes: 2
Reputation: 3026
With the limited information given, if you're trying to show the image in a div or img element, below shows two approaches.
$('input').change(function() {
var fr = new FileReader;
fr.onloadend = function() {
$("#target").attr('src', fr.result);
};
console.log(this.files[0]);
//fr.readAsDataURL(this.files[0]);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="file">
<img id="target">
$('input').change(function() {
var fr = new FileReader;
fr.onload = function() {
var img = new Image;
img.onload = function() {
var c = document.getElementById("cvs");
var ctx = c.getContext("2d");
ctx.drawImage(img, 0, 0, 200, 180);
}
img.src = fr.result;
};
console.log(this.files[0]);
fr.readAsDataURL(this.files[0]);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="file">
<canvas id="cvs"></canvas>
These would read your file and you can get dynamically the file name and other properties.
Upvotes: 0