Reputation:
I have a service which has a method that allows to obtain the profile image of a user.
users.service.ts
getPictureProfile() {
const headers = new HttpHeaders({ . . .});
const options = { headers };
const body = {...};
return this.http.post(environment.apiUrl + '/Users/GetPictureProfile', body, options);
}
Then I have a useful class called userHelper, which contains a method that should only return the image string in base64. The objective is to obtain the image chain from any component, without having to use subscribe again.
user-helper.ts
getPictureProfile(): any {
return this.usersService.getPictureProfile().subscribe(
(res: any) => {
console.log('=================res subscribe=================');
console.log(res);
return res;
},
err => {
return '';
}
);
}
Finally I have a component (The goal is that I can use it in any component), which calls the userHelper class method only to get the image string, but it returns an object.
getUserProfile() {
this.pictureProfile = this.userHelper.getPictureProfile();
console.log('==========this.pictureProfile==========');
console.log(this.pictureProfile);
}
How can I get the chain that returns the service without the need to reuse subscribe? (what is expected is the string below '================= res subscribe =================')
If you are wondering why I am using post and not get method on the service, it is because owasp recommends the use of the post method in the services (It is a bit safer especially using https).
Thanks for the help
Upvotes: 0
Views: 14717
Reputation: 3607
Pipeable operators to the rescue!
My suggestion would be to use a pipe
so you can do something like this:
getProfilePicture().pipe(map(picture: any)=>{return convertToBase64(picture)});
Your getProfilePicture()
method should return the Observable as-is and your helper convertToBase64()
simply receives a normal parameter (not an Observable) and returns the base64 accordingly
Upvotes: 0
Reputation: 24472
at user-helper.ts you can't return a value from subscription simply the observable run as async operation and the method is sync and the method will not wait until the observable return a value , you can update you code to use async/await is stil async operation but it 's look like sync flow
user-helper.ts
getPictureProfile() {
this.usersService.getPictureProfile().toPromise()
}
component
async getUserProfile() {
this.pictureProfile = await this.userHelper.getPictureProfile();
console.log('==========this.pictureProfile==========');
console.log(this.pictureProfile);
}
if you don't want to use async/await you have to make sure user helper method return the observable not subscribe inside it.
user-helper.ts
getPictureProfile(): any {
return this.usersService.getPictureProfile().pipe(
tap(res: any) => {
console.log('=================res subscribe=================');
console.log(res);
});
}
component
getUserProfile() {
this.userHelper.getPictureProfile().subscribe( res =>{
this.pictureProfile = res;
console.log('==========this.pictureProfile==========');
console.log(this.pictureProfile);
});
}
Upvotes: 1
Reputation: 2598
your service (http request) must return an observable where "any" type is your response object type.
getPictureProfile(): Observable<any> {
const headers = new HttpHeaders({ . . .});
const options = { headers };
const body = {...};
const url = environment.apiUrl + '/Users/GetPictureProfile';
return this.http.post(url, body, options)
.pipe(
map(result => {
return result;
})
);
}
Upvotes: 1