I'm trying out Dart, but I cant figure out, how to send an image from the user to the server. I have my input-tag, and i can reach this in the DART code, but i cant seem to read from it. Im trying something like:
InputElement ie = document.query('#myinputelement');
ie.on.change.add((event){<br/>
InputElement iee = document.query('#myinputelement');<br/>
FileList mfl = iee.files;<br/>
File myFile = mlf.item(0);<br/>
FileReader fr = new FileReader();
fr.readAsBinaryString(myFile);
String result = fr.result; //this is always empty
});
With the html containing:
<input type="file" id="myinputelement">
I really hope you cant help me, im kinda stuck. I might just be missing how to do the onload for the filereader, or maybe im doing it totally wrong.
The FileReader API is asynchronous so you need to use event handlers.
var input = window.document.querySelector('#upload');
Element log = query("#log");
input.addEventListener("change", (e) {
FileList files = input.files;
Expect.isTrue(files.length > 0);
File file = files.item(0);
FileReader reader = new FileReader();
reader.onLoad = (fileEvent) {
print("file read");
log.innerHTML = "file content is ${reader.result}";
};
reader.onerror = (evt) => print("error ${reader.error.code}");
reader.readAsText(file);
});
you also need to allow file uploads from to your browser, which can be done in Chrome by starting it with the flag --allow-file-access-from-files
This is how to read a file using dart:html
.
document.querySelector('#myinputelement`).onChange.listen((changeEvent) {
List fileInput = document.querySelector('#myinputelement').files;
if (fileInput.length > 1) {
// More than one file got selected somehow, could be a browser bug.
// Unless the "multiple" attribute is set on the input element, of course
}
else if (fileInput.isEmpty) {
// This could happen if the browser allows emptying an upload field
}
FileReader reader = new FileReader();
reader.onLoad.listen((fileEvent) {
String fileContent = reader.result;
// Code doing stuff with fileContent goes here!
});
reader.onError.listen((itWentWrongEvent) {
// Handle the error
});
reader.readAsText(fileInput[0]);
});
It's not necessary (any more) to use dart:dom FileReader instead of the one from dart:html.
Your code should work if you add an event listener to the file reader, like this:
FileReader fr = new FileReader();
fr.on.load.add((fe) => doSomethingToString(fe.target.result));
fr.readAsBinaryString(myFile);
My attempt
void fileSelected(Event event) async {
final files = (event.target as FileUploadInputElement).files;
if (files.isNotEmpty) {
final reader = new FileReader();
// ignore: unawaited_futures
reader.onError.first.then((evt) => print('error ${reader.error.code}'));
final resultReceived = reader.onLoad.first;
reader.readAsArrayBuffer(files.first);
await resultReceived;
imageReference.fileSelected(reader.result as List<int>);
}
}
Thanks to the help from this post, I got it to work. I still utilized my event handler in the input tag and made sure that I DID NOT import both dart:io and dart:html, only dart:html is needed.
This is what my final AppComponent looked like.
import 'dart:html';
import 'package:angular/angular.dart';
@Component(
selector: 'my-app',
styleUrls: ['app_component.css'],
templateUrl: 'app_component.html',
directives: [coreDirectives],
)
class AppComponent {
// Stores contents of file upon load
String contents;
AppComponent();
void fileUpload(event) {
// Get tag and the file
InputElement input = window.document.getElementById("fileUpload");
File file = input.files[0];
// File reader and event handler for end of loading
FileReader reader = FileReader();
reader.readAsText(file);
reader.onLoad.listen((fileEvent) {
contents = reader.result;
});
}
}
This is what my template looks like:
<h1>File upload test</h1>
<input type="file" (change)="fileUpload($event)" id="fileUpload">
<div *ngIf="contents != null">
<p>Hi! These are the contents of your file:</p>
<p>{{contents}}</p>
</div>