I have the below typescript code.
I tried to make the packageFiles method an Observable so I can wait until it's done before I move on. But somethings not right?
packageFiles(): Observable<any> {
var filesToSend = [];
//Loop through files
this.files.forEach(f => {
var reader = new FileReader();
reader.onload = (e) => {
//
var fileForUpload = new FileForUpload();
var encodedString = window.btoa(<string>reader.result);
fileForUpload.FileValue = encodedString;
fileForUpload.FileName = f.name;
fileForUpload.FileType = f.type;
//
filesToSend.push(fileForUpload);
console.log(filesToSend);
};
reader.readAsDataURL(f);
});
return of(filesToSend);
}
this method calls this then:
uploadFiles() {
var response = this.packageFiles()
.subscribe(
data => {
console.log("data");
console.log(data);
},
error => {
}
);
}
You're synchronously returning an observable of an empty array here, which isn't what you want to do. You need to make sure you first collect the data and then emit on an observable (of
emits immediately and then completes).
Let's assume for a second that you only had a single file
. In this case, closest to your code would be using a Subject
:
packageFiles(): Observable<FileForUpload> {
const result$ = new Subject<FileForUpload>();
const reader = new FileReader();
reader.onload = () => {
const fileForUpload = new FileForUpload();
// … do your stuff …
result$.next(fileForUpload);
result$.complete();
};
// …
return result$;
}
However, this returns a hot observable, and likely it'd be better here to return a cold observable instead:
packageFiles(): Observable<FileForUpload> {
return Observable.create(observer => {
const reader = new FileReader();
reader.onload = () => {
const fileForUpload = new FileForUpload();
// … do your stuff …
observer.next(fileForUpload);
observer.complete();
};
// …
});
}
Now you just need to generalize this to multiple files. Let's rename this into packageFile
and pass the file as an input:
packageFile(file: File): Observable<FileForUpload> {
// …
}
Then we can write the actual function as
packageFiles(): Observable<FileForUpload[]> {
return forkJoin(...this.files.map(file => this.packageFile(file)));
}
… which you can now use by calling
this.packageFiles().subscribe(filesToUpload => { /* … */ });
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments