1
votes

I've got a interesting situation here which I'm trying to understand which is the best way to write this code.

I've got a service which I use to inject in a component to fetch data from the server which returns an observable. Here is the code :

getDataFromServer(): Observable<any> {
    this.storage.get('access_token').then((access_token) => {
        let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': 'Bearer ' + access_token });
        let options = new RequestOptions({ headers: headers }); 
    });

  return this.http.get(config.apiArticlesUrl, options)
  .map(this.extractData)
  .catch(this.handleError); 
}

So as you can see here this method is expected to return Observable. It also has a storage method being executed inside the method body which returns a promise with resulting data needed to fetch the data from the server using a Bearer token.

Now, Typescript complains that in this case the options variable is being undefined at this point because of scoping issue. If I defined options variable outside the .then(function) body then all the time options variable will be empty because of the promise execution and I can authenticate to the server because of that.

If I put return this.http.get(config.apiArticlesUrl, options).map(this.extractData).catch(this.handleError); inside the .then(function{}) body then TypeScript will complain that Observable needs to return from this method.

The important part is that I'm using import { Storage } from '@ionic/storage'; which whenever you use .get method it always returns a Promise which is not a good practice to change 3rd party core code.

The question is : Which is the best way to write this code so whenever I subscribe to the Observable I will get the user authenticated combining Promise and Observable?

I hope I'm asking the question in the right format and if it's possible to share some link where this is all explained in a clean way that would be very useful.

Cheers.

1
you should not use Observable and Promise together as both are two end points. You can see the best way in this answer if you need more info let me know - Aravind
I've just quickly updated my question. I don't think I will be able to implement the solution you've just shared with me since I cannot change 3rd party code in this case (Storage) from @ionic/storage module. - Rambo
you can use the way of usage and generic way of handling services - Aravind

1 Answers

0
votes

Here is how I've solved this issue.

I've restructured the service method to look like this :

  getDataFromServer(): Promise<any> {
      return this.storage.get('access_token').then((access_token) => {
             let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': 'Bearer ' + access_token });
             let options = new RequestOptions({ headers: headers }); 

             return this.http.get(config.apiArticlesUrl, options);
     });
   }

And the place where I wanted this to be executed I've used this code :

this.dataService.getDataFromServer().then(
  (data) => {
    console.log("data:",data);
    data.subscribe((data)=>{
      console.log("This is the data : ", data);
    },
     (err) => console.log("err :",err)
    )
  },
     (err)=>console.log("err",err)
  )

And it works great. Still I can't say that the commented solution is not a good (better practice to implement) however since there are different types of situations I wanted to share this type of solution.