How to solve undefined promises in Ionic Cordova?

In my web browser, the Promise object is “fulfilled”, the result is a value, but when I build it in the mobile app the Promise object is “pending” (working), the result is undefined.
Here is my code below

api_url:any;

async getApiURLPromise() {
  return await new Promise(resolve => {
    this.http.get("https://www.sample_api.com/api/production")
      .subscribe(data => {
        this.api_url = data['apiurl'];
        console.log("PROMISE TO HER THIS API URL - " + this.api_url);
        resolve(this.api_url);
    });
    }).catch(error => {
      console.log("PROMISE REJECTED BECAUSE YOU BROKE IT - " + error 
      + " - " + JSON.stringify(error));
    });
}

Is this meant to be production code?

If so then some thoughts

  • dont use new Promise
  • if u insist converting an Observable to a Promise, use toPromise(), even though it is a bit of a waste
  • better to have the caller of the function getApiURLPromise subscribe and use the result, either subscribe or then the toPromise()
  • if the http does not finish then there is a networking/adressing problem, especially when things seem to work in a different environment
1 Like

Because you never resolved or rejected that promise in case of an error at subscription.

    this.http.get("https://www.sample_api.com/api/production")
      .pipe(
           catchError(err => {
                 reject(err);
                 return throwError(err);
           })
       )
      .subscribe(data => {

i use the function like this it is simple

getApiURLPromise() {
     this.http.get("https://www.sample_api.com/api/production")
      .subscribe(data => {
        this.api_url = data['apiurl'];
      });
 }

So what should I do when I don’t use new Promise? Can you give me a code for that

Read and emulate Tour of Heroes Chapter 6.

1 Like

Yup- that is the full story!

async getApiURLPromise() {
  return await new Promise(resolve => {
    this.http.get("https://www.sample_api.com/api/production")
      .pipe(
          catchError(error => {
            resolve(error);
            return throwError(error);
          }))
      .subscribe(data => {
        this.api_url = data['apiurl'];
        console.log("PROMISE THIS API URL TO HER- " + this.api_url);
        resolve(this.api_url);
    });
    }).catch(error => {
      console.log("PROMISE REJECTED BECAUSE YOU BROKE IT - " + error);
  });

Sorry for the late reply. You mean like this one?

Problems I have with the code in the above post:

  • it does not declare a return value kind
  • the method name does not describe what it does in terms a consumer would understand
  • it creates a needless Promise
  • I don’t understand the purpose or implied contract of the attempted error handling
  • there are two levels of incomprehensible error handling
  • it subscribes to Observables in the same place they are made
  • there is no typing on the get call
  • it is using subscriptions instead of transformation operators
  • it modifies external state from inside a subscription, with no way of knowing when this has happened
getApiURL() {
  return this.http.get("https://www.sample_api.com/api/production")
      .pipe(map(data=>data['apiurl']))
}         

and then the caller should subscribe pending the way you want it to handle the url. If it is only showing, then maybe use async-pipe, etc.

(not addressing all the considerations by @rapropos)

1 Like

That addresses 95% of them, and look how much cleaner it is.

Give it a return type with getApiUrl(): Observable<string> and it looks great.

1 Like