0
votes

I have a service's method which should return a string, but instead it returns a "Subscriber": enter image description here

Service:

getRedirectPage = (role) => {
    let destinationPage = null;
    return this.privilegePageService.getAllPrivilegesPage().subscribe(data => {
      this.privilegePage = data;

      return this.userService.getUserRolesList().subscribe(data => {

        let currentRole = data.filter(x => x.name === role.name)[0];
        currentRole = this.sortPagePrivileges(currentRole);
        //  Partial fix for ROLES without privileges
          loop1:
          for(let priv of currentRole.privileges) {
          loop2:    
              for(let privPage of this.privilegePage) {
                  if(priv.name == privPage["privileges"] + "_PRIVILEGE") {
                      destinationPage = privPage["page"];
                      break loop1;    //  Breaking out from both loops
                  }
              }
        }
        return destinationPage;
      }, error => this.errorHandler.handleError(error));
    });
  }

Component:

 redirectOnRole = (role) => {
      let destinationPage = this.redirectPageService.getRedirectPage(role);
      console.log("destinationPage: ", destinationPage); 
}

So the returned destinationPage needs to be a string. Can you please advise what am I doing wrong? Thanks!

UPDATE:

If I do it into the Component like this:

this.redirectPageService.getRedirectPage(role).subscribe(let destinationPage = data);

I get an error which it says Property 'subscribe' does not exist on type 'Subscription'. That's why I tried without the subscribe.... Into the service I am returning a method from another service to which I am also subscribing, that's why it doesn't work: return this.privilegePageService.getAllPrivilegesPage().subscribe(data => {...

UPDATE 2

I managed to get the data as an Observable from the service and to subscribe to it into the component, but I would like to improve the way I did it. Into the component I get an Observable inside another Observable and I am wondering if this can be changed to receive the data into the main Observable. Here is my code:

SERVICE:

getRedirectPage = (role):Observable<any> => {
    let destinationPage = null;
    return from(this.privilegePageService.getAllPrivilegesPage().map(data => {
      this.privilegePage = data;

      return this.userService.getUserRolesList().map(data => {

        let currentRole = data.filter(x => x.name === role.name)[0];
        currentRole = this.sortPagePrivileges(currentRole);
        // Other code / assign a string to 'destinationPage'
        return destinationPage;
      }, error => this.errorHandler.handleError(error));
    }));
}

COMPONENT:

redirectOnRole = (role) => {
   this.redirectPageService.getRedirectPage(role).subscribe(data => {
        data.subscribe(destinationPage => {
            this._router.navigate([destinationPage]);
        });
    });
};

Please advise! Thanks!

2
That's not how you use Observables. Subscribing to an Observable does return a subscriber. You should get your data (as you do) inside the subscription. this.userService.getUserRolesList().subscribe(data => { // only here you can have your data } - Roberto Zvjerković
I know how that I have to subscribe into the Component, but it doesn't work in this case. Please see the updated question. - decebal
Your service should return observable<string> in order to subscribe in component. - Eldho
I will look this into details - Eldho
I know how that I have to subscribe into the Component, That might be true, but it seems that you actually dont know what does such subscription means, how Observables work, nor how to work with them. Just saying. - Antoniossss

2 Answers

0
votes

You are returning subscriber here

 return this.privilegePageService.getAllPrivilegesPage().subscribe....

so this is what you get - the subscriber (or Subscribtion).

0
votes

A common operation in any web application is getting or posting data to a server. Angular applications do this with the Http library, which previously used Promises to operate in an asynchronous manner. The updated Http library now incorporates Observables for triggering events and getting new data

Http library's common routines like get, post, put and delete all return Observables that allow us to asynchronously process any resulting data.

component

redirectOnRole = (role) => {
   this.redirectPageService.getRedirectPage(role).subscribe(x=> {
    let destinationPage = x;
  });
}

Service Change your service to return observable in the method which have better readability.

This is pseudo code which to show only the concept. I haven't used IDE so it contains typos and syntax errors

getRedirectPage(role:yourType) :Observable<string> {
    Observable.forkJoin(
        this.privilegePageService.getAllPrivilegesPage().map((res:Response) => res.json()),
        this.userService.getUserRolesList()
                            .flatMap((response) => response.json())
                            .filter((x) => x.name==role.name)
    ).subscribe(
      data => {
        this.privilegePage = data[0]
        this.role= data[1]
           if(your condition) {
             return // string observable.
         }
      },
      err => console.error(err)
    );
  }

how it works

The Component initiates the actual GET operation by subscribing to the Observable returned by this service method.

When the server responds successfully with the result, the component assign that destinationPage which will be updated on the view.

Angular http reference