2017-04-21 54 views
0

我正在使用离子本机SQLite数据库的离子应用程序和在浏览器中测试我使用WebSQL。 它在浏览器中工作正常,但在Android设备上运行应用程序时。它给我错误像Cannot read property 'transaction' of undefined。 以下是供参考的代码。SQLiteObject未定义在离子3

1)DBProvider.ts

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

declare var window: any; 
@Injectable() 
export class DBProvider { 
    DB_NAME: string = 'DailySheet.db'; 
    public websql = null; 
    public sqlite: SQLite; 
    sqliteobj: any; 
    public AppUsers = []; 

    constructor(public platform: Platform) { 
     if (this.platform.is('core')) { 
      this.websql = window.openDatabase(this.DB_NAME, "1.0", "Test DB", 2 * 1024 * 1024); 
      console.log('Database opened.'); 
      this.createTable(); 
     } 

     this.platform.ready().then(() => { 
      if (!this.platform.is('core')) { 
       this.sqlite.create({ name: this.DB_NAME, location: 'default' }) 
        .then((db: SQLiteObject) => { 
         console.log('Database opened.'); 
         this.sqliteobj = db; 
         this.createTable(); 
        }); 
      } 
     }); 
    } 

    createTable() { 
     this.query(`CREATE TABLE IF NOT EXISTS AppUser (
         UserId INTEGER NOT NULL, 
         MobileNo TEXT NOT NULL UNIQUE, 
         Email TEXT, 
         PRIMARY KEY(UserId) 
        )`) 
      .then(data => { 
       console.log('Table created.'); 
      }) 
      .catch(err => { 
       console.error('Unable to create initial storage tables', err.tx, err.err); 
      }); 
    } 

    getAppUsers(): Promise<any> { 
     let query = 'SELECT * FROM AppUser'; 
     return this.query(query) 
      .then(data => { 
       if (data.res.rows.length > 0) { 
        console.log('Rows found.'); 
        return data.res.rows; 
       } 
       else { 
        console.log('No rows found.'); 
       } 
      }); 
    } 

    insertAppUser(): Promise<any> { 
     let id = 1; 
     let mobileno = '8905606191'; 
     let email = '[email protected]'; 

     return this.query('INSERT INTO AppUser (UserId, MobileNo, Email) VALUES (' + id + ' ,\"' + mobileno + '\" ,\"' + email + '\")') 
      .then(data => { 
       console.log('Insert success.'); 
       return data; 
      }) 
      .catch(err => { 
       console.error('Unable to insert', err.tx, err.err); 
      }); 
    } 

    updateAppUser(UserId): Promise<any> { 
     let query = "UPDATE Todo SET Email=? WHERE UserId=?"; 
     return this.query(query, ['[email protected]', UserId]) 
      .then(data => { 
       console.log('AppUser Updated.'); 
       return data; 
      }) 
      .catch(err => { 
       console.error('Unable to update', err.tx, err.err); 
      }); 
    } 

    deleteAppUser(UserId): Promise<any> { 
     let query = "DELETE FROM AppUser WHERE UserId=?"; 
     return this.query(query, [UserId]) 
      .then(data => { 
       return data; 
      }) 
      .catch(err => { 
       console.error('Unable to delete', err.tx, err.err); 
      }); 
    } 

    query(query: string, params: any[] = []): Promise<any> { 
     return new Promise((resolve, reject) => { 
      try { 
       if (this.platform.is('core')) { 
        this.websql.transaction((tx: any) => { 
         tx.executeSql(query, params, 
          (tx: any, res: any) => resolve({ tx: tx, res: res }), 
          (tx: any, err: any) => reject({ tx: tx, err: err })); 
        }, 
         (err: any) => reject({ err: err })); 
       } 
       else { 
        this.sqliteobj.transaction((tx: any) => { 
         tx.executeSql(query, params, 
          (tx: any, res: any) => resolve({ tx: tx, res: res }), 
          (tx: any, err: any) => reject({ tx: tx, err: err })); 
        }, 
         (err: any) => reject({ err: err })); 
       } 
      } catch (err) { 
       reject({ err: err }); 
      } 
     }); 
    } 
} 

2)home.ts

import { Component, OnInit } from '@angular/core'; 
import { NavController, Platform } from 'ionic-angular'; 
import { DBProvider } from '../../providers/DBProvider'; 

@Component({ 
    selector: 'page-home', 
    templateUrl: 'home.html' 
}) 
export class HomePage implements OnInit { 
    AppUsers: Array<Object>; 

    constructor(public navCtrl: NavController, private platform: Platform, public db: DBProvider) { 
    } 

    ionViewDidLoad() { 
    this.deleteAppUser(); 
    this.insertAppUser(); 
    this.getAllAppUsers(); 
    } 

    ngOnInit() { 
    } 

    public deleteAppUser() { 
    this.db.deleteAppUser(1) 
     .then(data => { 
     if (data.res.rowsAffected == 1) { 
      console.log('AppUser Deleted.'); 
     } 
     else { 
      console.log('No AppUser Deleted.'); 
     } 
     }) 
     .catch(ex => { 
     console.log(ex); 
     }); 
    } 

    public insertAppUser() { 
    this.db.insertAppUser() 
     .then(data => { 
     }) 
     .catch(ex => { 
     console.log(ex); 
     }); 
    } 

    public getAllAppUsers() { 
    this.db.getAppUsers() 
     .then(data => { 
     this.AppUsers = data; 
     }) 
     .catch(ex => { 
     console.log(ex); 
     }); 
    } 

} 

调试时,我在浏览器和移动想出在差序列有所该代码运行。

在浏览器

  1. DBProvider构造
  2. this.CreateTable()函数(DBProvider.ts)
  3. this.deleteAppUser()函数(home.ts)
  4. this.insertAppUser()函数(home.ts)
  5. this.getAllAppUsers()函数(home.ts)

在Android装置

  1. DBProvider构造
  2. this.deleteAppUser()函数(home.ts)
  3. this.insertAppUser()函数(home.ts)
  4. this.getAllAppUsers()函数( home.ts)
  5. this.CreateTable()函数(DBProvider.ts)

正如你可以this.sqliteobj被分配在DBProvider构造。但调试时,我发现来自home.ts的函数在调用sqliteobj之前调用,这就是为什么它给出了一个错误,如Cannot read property 'transaction' of undefined。但接下来的问题是为什么在这个sqliteobj被赋值之前,home.ts函数会被调用?

+0

我终于找到了解决方案,但是堆栈溢出不能让我发布答案。 [这里](https://forum.ionicframework.com/t/ionic-native-sqlite-issue/87416/4)你可以得到解决方案。 –

回答

1

据我所知,在sqlite数据库的每次调用中都需要this.sqlite.create(...。所以你必须在sqliteobj之前将它包含在你的查询函数中。