How to make FileReader work with Angular2!!
When reading a file from client side with Angular2 and Typescript,
I try to us
I would create a method like below
readFileContent(file: File): Promise<string | ArrayBuffer> {
return new Promise<string | ArrayBuffer>((resolve, reject) => {
const myReader: FileReader = new FileReader();
myReader.onloadend = (e) => {
resolve(myReader.result);
};
myReader.onerror = (e) => {
reject(e);
};
myReader.readAsText(file);
});
}
and call it like
const content = await this.readFileContent(inputValue.files[0])
a little late to the party here. This can also be done creating the FileReader as service. This would help the unit tests and will decouple the FileReader from the component that is using it.
you can create the token like this:
export const FileReaderService = new InjectionToken<FileReader>('FileReader', {
factory: () => new FileReader(),
});
And then you can use it as like this: (I believe it could be used as a regular service. I haven't tested it yet. But the way I am showing here works just fine)
class MyService { // this could be a component too
constructor(@Inject(FileReaderService) private reader: FileReader) {}
readFile() {
const file = // the file you want to read
this.reader.onload = // whateever you need
this.reader.readAsDataURL(file)
}
}
Just add
fr.readAsText(event.files[0]);
After the onLoad definition.
Maybe this can help you, this is my upload handler function for the file upload library of primeng
archivoUploadHandler(event) {
let contenido;
let fr = new FileReader();
fr.onload = (e) => {
contenido = fr.result;
console.log(contenido);
};
fr.readAsText(event.files[0]);
}
First you have to specify the target of the change event on input form in template:
@View({
template:`
<div>
Select file:
<input type="file" (change)="changeListener($event)">
</div>
`
})
As you can see I binded a changeListener()
method to (change)
event. My implementation of class:
changeListener($event) : void {
this.readThis($event.target);
}
readThis(inputValue: any) : void {
var file:File = inputValue.files[0];
var myReader:FileReader = new FileReader();
myReader.onloadend = function(e){
// you can perform an action with readed data here
console.log(myReader.result);
}
myReader.readAsText(file);
}
Listener is passing file from event to readThis
method. Read this have implemented it's own FileReader
. You can also define FileReader in component instead in function.
answer from @haz111 already works, but just in case you want to make file reader a reusable component , you could possibly use this or better: improve on this:
inputfilereader.ts
import {Component, ElementRef, EventEmitter} from 'angular2/angular2';
@Component({
selector: 'filereader',
templateUrl: './commons/inputfilereader/filereader.html',
styleUrls: ['./commons/inputfilereader/filereader.css'],
providers: [ElementRef],
events : ['complete']
})
export class InputFileReader {
complete :EventEmitter = new EventEmitter();
constructor(public elementRef: ElementRef) {
}
resultSet:any; // dont need it
changeListener($event: any) {
var self = this;
var file:File = $event.target.files[0];
var myReader:FileReader = new FileReader();
myReader.readAsText(file);
var resultSet = [];
myReader.onloadend = function(e){
// you can perform an action with data read here
// as an example i am just splitting strings by spaces
var columns = myReader.result.split(/\r\n|\r|\n/g);
for (var i = 0; i < columns.length; i++) {
resultSet.push(columns[i].split(' '));
}
self.resultSet=resultSet; // probably dont need to do this atall
self.complete.next(self.resultSet); // pass along the data which would be used by the parent component
};
}
}
filereader.html
<input type="file" (change)="changeListener($event)" />
Usage in other files
anotherfile lets say dfs.ts
import {Component, ElementRef} from 'angular2/angular2';
import {InputFileReader} from '../../commons/inputfilereader/inputfilereader';
@Component({
selector: 'dfs',
templateUrl: './components/dfs/dfs.html',
styleUrls: ['./components/dfs/dfs.css'],
providers: [ElementRef],
directives:[InputFileReader]
})
export class DfsCmp {
constructor(public eleRef :ElementRef) {}
callSomeFunc(data):void {
console.log("I am being called with ", data);
}
}
dfs.html
<filereader (complete)="callSomeFunc($event)"></filereader>