Reputation: 1612
I am trying to convert uploaded csv file to base 64 in an angular service. If I use the same method, it works fine in a component but when I am calling from a service, it gets null value.
Component
public upload(files) {
this.uploadedFile = this.service.getBase64(this.file); // This does not work
// this.getBase64(this.file); // This works if method is in same component
}
}
getBase64() {
const myReader = new FileReader();
myReader.onloadend = e => {
this.uploadedFile = myReader.result.toString().split(',')[1];
};
myReader.readAsDataURL(this.file);
}
This works fine but now when I call the method using service, it does not work
Service
getBase64(file: any){
const myReader = new FileReader();
let base64File: any;
myReader.onloadend = e => {
base64File = myReader.result.toString().split(',')[1];
};
myReader.readAsDataURL(file);
return base64File;
}
Service returns null/undefined value. How can I keep base64 function in a service layer. Service is working correctly as there are multiple functions inside the service.
Upvotes: 1
Views: 1857
Reputation: 3236
You are using an asynchronous method, and try to return a synchronous data. It works inside the same component because you do not use the return statement, you directly set the new value in its variable (you can replace this.uploadedFile = this.service.getBase64(this.file);
with this.service.getBase64(this.file);
, it would have the same result since your method does not return anything)
In a different class, you have to use a Subject to be able to subscribe to it:
// Service
uploadedFile$: Subject<string> = new Subject<string>();
updateBase64(file: any) {
const myReader = new FileReader();
myReader.onloadend = e => {
this.uploadedFile$.next(myReader.result.toString().split(',')[1]);
};
myReader.readAsDataURL(file);
}
getBase64(): Observable<string> {
return this.uploadedFile$.asObservable();
}
// Component
base64Subscribtion: Subscribtion;
constructor(public service: MyAppService) {
this.base64Subscribtion = this.service.getBase64()
.subscribe(result => this.uploadedFile = result); // receive new value from service when it is ready
}
public upload(files) {
this.service.updateBase64(this.file); // asks the service to update its value
}
ngOnDestroy() {
this.base64Subscribtion.unsubscribe(); // since a Subject never ends, you have to cancel manually subscribtion, otherwise your component will never be able to die (memory leak)
}
Upvotes: 1