Promise not executed correctly


#1
import { Injectable } from '@angular/core';
import { Platform } from 'ionic-angular';
import { SQLite, SQLiteObject } from '@ionic-native/sqlite';

//TODO: define options globally
//TODO: location can be hardcoded

@Injectable()
export class DBProvider {
  // indicates if Promise is resolved (https://forum.ionicframework.com/t/ionic-2-3-and-sqlite/91326/2)
  public databaseCreated: Promise<void>;
  public tempItems: Array<{id: string, title: string, inclass: string, created: string}>;

  constructor(public platform: Platform, public sqlite: SQLite) {
    this.databaseCreated = this.create()
    this.tempItems = []
  }

  public create(): Promise<void> {
    return this.platform.ready().then(() => {
      this.sqlite.create({
        name: 'teacherApp.db',
        location: 'default'
      })
        .then((db: SQLiteObject) => {
          db.executeSql('create table if not exists lists(uuid STRING PRIMARY KEY, title TEXT, inclass STRING, created STRING)', {})
            .then(() => console.log('Created / Opened SQL'))
            .catch(e => console.log(e));

        })
        .catch(e => console.log(e));
    })
  }

// clear and then refill
  public dropTableLists(): Promise<void> {
    return this.platform.ready().then(() => {
      this.sqlite.create({
        name: 'teacherApp.db',
        location: 'default'
      })
        .then((db: SQLiteObject) => {
          db.executeSql('drop table if exists lists', [])
            .then(() => console.log('Deleted lists from SQL'))
            .catch(e => console.log(e));
        })
        .catch(e => console.log(e));
    }).then(()=>this.create())
  }

  public addItem(uuid, title, inclass, created) {
    this.databaseCreated.then(() => {
      this.sqlite.create({
        name: 'teacherApp.db',
        location: 'default'
      })
        .then((db: SQLiteObject) => {
          db.executeSql("INSERT INTO lists VALUES (?,?,?,?)", [uuid, title, inclass, created])
            .then((data) => console.log("INSERTED: " + JSON.stringify(data)))
            .catch(e => console.log(e));
        })
        .catch(e => console.log(e));
    })
  }

  public refreshItems(): Promise<void> {
    this.tempItems = [];
  return  this.databaseCreated.then(() => {
    this.sqlite.create({
        name: 'teacherApp.db',
        location: 'default'
      })
        .then((db: SQLiteObject) => {
          db.executeSql('SELECT * FROM lists', [])
            .then((data) =>
            {
              if(data.rows.length > 0) {
                for(var i = 0; i < data.rows.length; i++) {
                    this.tempItems.push(data.rows.item(i));
                }
            }
          })
            .catch(e => console.log(e));
        })
        .catch(e => console.log(e));
    })
  }
}

The promise in the create function (which is passed to databaseCreated) is kind of ignored. In my page I call

public uuid: IDGenerator, public popoverCtrl: PopoverController, public storage: DBProvider) {
    this.items = [];
    this.storage.databaseCreated.then(() => {this.items = this.storage.tempItems;})
  }

but the program doesn’t wait until the promise is fullfilled and executes the code at start.


#2

When chaining together promises you have to return a promise, so you need to change them to look something like this:

    return this.platform.ready().then(() => {
      return this.sqlite.create({ //<- HERE
        name: 'teacherApp.db',
        location: 'default'
      })
        .then((db: SQLiteObject) => {
          //HERE:
          return db.executeSql('create table if not exists lists(uuid STRING PRIMARY KEY, title TEXT, inclass STRING, created STRING)', {})
            .then(() => console.log('Created / Opened SQL'))
            .catch(e => console.log(e));

        })
        .catch(e => console.log(e));
    })

#3

There is one sort-of-exception to this: arrow functions with a single expression and no braces have an implicit return.

foo.then((a) => frobulate(a));

is equivalent to

foo.then((a) => {
  return frobulate(a);
});

which (as pointed out by @SigmundFroyd above) is not the same as:

foo.then((a) => {
  frobulate(a);
});