user8564782
user8564782

Reputation:

return value from subscribe in service angular 8

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);
  }

The result is as follows enter image description here

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

Answers (3)

WSD
WSD

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

Muhammed Albarmavi
Muhammed Albarmavi

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

AlleXyS
AlleXyS

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

Related Questions