Wang
Wang

Reputation: 15

Ionic 3/Typescript Promise

Im trying to use Promise to get data from web service

  login(){
var obj = {email:'WHATEVER', firstname:''};
var b = this.getUsers().then(data => {
  this.films = data;
  obj = this.films.customer_info;
  console.log('inside:' + obj.firstname);
});
console.log('outside:' + obj.firstname);

}

My expected result:

outside:Nam Nam login.ts:51 inside:Nam Nam
login.ts:48

My actual result :

outside: login.ts:51 inside:Nam Nam
login.ts:48

Can someone tell me how to solve this problem? thanks

Upvotes: 1

Views: 11893

Answers (1)

Fenton
Fenton

Reputation: 250822

Your expected result is not possible, because you are asserting that you want a value (that will be obtained asynchronously) to be available synchronously.

Let's look into it in more detail... here is a short, but fully working example of your problem:

class Example {
  private films: any;

  login() {
    var obj = { email: 'WHATEVER', firstname: '' };
    var b = this.getUsers().then(data => {
      this.films = data;
      obj = this.films.customer_info;
      console.log('inside:' + obj.firstname);
    });
    console.log('outside:' + obj.firstname);
  }

  getUsers() {
    return new Promise((resolve, reject) => {
      window.setTimeout(() => {
        console.log('Result obtainined... for example from a service');
        resolve({ customer_info: { firstname: 'Fenton' } });
      }, 1000);
    })
  }
}

const example = new Example();

example.login();

The output from this program is:

outside:
Result obtainined... for example from a service
inside:Fenton

As you can see, the statement that is outside of the then handler executes before the promise resolves. If you are calling out to a service, this line of code will run before the server has responded.

That's actually the whole point of promises - which is why it works inside your then handler.

If you have code that depends on the login completing, you could return a promise from the login method. Based on the above example, you could use:

  login(): Promise<{ firstname: string}> {
    return new Promise((resolve, reject) => {
      this.getUsers().then(data => {
        this.films = data;
        resolve(this.films.customer_info);
      });
    });
  }

When the login completes, the customer info is available:

example.login()
    .then((customer) => console.log(customer.firstname));

Upvotes: 3

Related Questions