0

The code is written in Angularjs in Ionic framework. I think people from Angular background can also answer this question.

When I call this function alert shows empty array "[]" and "undefined" respectively. I think this is happening cause of the asynchronous nature of JavaScript. I want this function to execute synchronously.

 /*This is the constructor */
 constructor(public navCtrl: NavController, public SP: SqliteProvider) {
 }
 /*my function*/
 getCustomerById()
 {
     this.SP.getCustomerById(this.id);
     this.customerById  = this.SP.customerById; 
        alert(this.SP.customerById);
        alert(this.SP.customerById[0]);

 }

/* The function in SqliteProvider */

 getCustomerById(cid)
{
    this.customerById = [];
    this.sqlite.create({
        name: this.dbName,
        location: 'default'
    })
        .then((db: SQLiteObject) =>{

            db.executeSql('SELECT * FROM `customers` WHERE id= ?', [cid])
                .then(result => {

                        var json = JSON.parse(result.rows.item(0).json);
                        //alert(json);
                        this.customerById.push(json);
                       // alert(JSON.stringify(this.customerObject));
                })
                .catch(e => console.log(e));
        })
        .catch(e => console.log(e));
}
  • `I want this function to execute synchronously` <= **no, you don't.** You just do not know how to use asynchronous calls correctly. Read the above duplicate link's answer, specifically the heading named **ES2015+: Promises with then()** which is similar to what `sqllite.create` and `db.executeSql` return. You need to return a promise to your caller so the caller (getCustomerById) can subscribe to it. – Igor Oct 19 '17 at 10:16

1 Answers1

0

Can you post the code from the SqliteProvider method? I am pretty sure it returns either a Promise or an Observable.

The thing with Promises and Observables are that the caller must wait until they have finished their job and then proceed, in a closure method.

So you should do something like the following:

this.SP.getCustomerById(this.id).then((customer) => {
    this.SP.customerById = customer;
    alert(this.SP.customerById);
}, error => {console.log(error)});

Note that in case your SqliteProvider method returns an Observable and not a Promise, you will have to change the code accordingly (add subscribe instead of then)

You can read an awesome tutorial for Promises here and for Observables here.

EDIT after posted method:

See also this answer. There is actually no need to have an inner customerById variable. Actually it;s not a good practice, since your method should only retrieve the customer, not assigning it to a variable. You should alter your code as following:

 getCustomerById(cid)
{
    return
    this.sqlite.create({
        name: this.dbName,
        location: 'default'
    })
        .then((db: SQLiteObject) =>{
            return
            db.executeSql('SELECT * FROM `customers` WHERE id= ?', [cid])
                .then(result => {
                   return JSON.parse(result.rows.item(0).json);
                })
                .catch(e => console.log(e));
        })
        .catch(e => console.log(e));
}
Paul Isaris
  • 414
  • 4
  • 13