带有 Ionic 4 的 SQLite?无法读取未定义类型错误的属性“then”:无法读取未定义的属性“then”

Posted

技术标签:

【中文标题】带有 Ionic 4 的 SQLite?无法读取未定义类型错误的属性“then”:无法读取未定义的属性“then”【英文标题】:SQLite with Ionic 4? Cannot read property 'then' of undefined TypeError: Cannot read property 'then' of undefined 【发布时间】:2018-09-25 19:28:32 【问题描述】:

首先我有this error,我解决了它。好的,不错。当我尝试使用我的设备(使用ionic cordova run android)进行调试时。数据库 SQL 没有加载,它显示好像什么都没有或从未创建数据库 sqlite。我检查了控制台,我看到了这个:

ERROR 错误:未捕获(承诺中):TypeError:无法读取 >undefined 的属性 'then' TypeError:无法读取未定义的属性“then” 在 AppComponent.push../src/app/app.component.ts.AppComponent.createDatabase >(app.component.ts:101) 在 app.component.ts:87

在 app.component.ts 我有这个:

import  SQLite, SQLiteObject  from '@ionic-native/sqlite/ngx';
import  DbService  from './services/db/db.service';


rootPage: string = null;
constructor(
    private platform: Platform,
    private splashScreen: SplashScreen,
    private statusBar: StatusBar,
    private translate: TranslateService,
    private router: Router,
    private menuCtrl: MenuController,
    public DbService: DbService,
    public sqlite: SQLite
    //private screenOrientation: ScreenOrientation
  ) 
    this.initializeApp();
  

  public TableCreated = "POR EL MOMENTO NO";
  public ahora = "ahora";

  initializeApp() 
    this.platform.ready().then(() => 
      this.statusBar.styleDefault();
      this.splashScreen.hide();
      this.translate.setDefaultLang('en');
      this.createDatabase();

    );
  

  closeMenu() 
    this.menuCtrl.close();
  

  private createDatabase()
    this.sqlite.create(
      name: 'data.db',
      location: 'default' // the location field is required
    ).then((db: SQLiteObject) =>   <<<<----- ERROR HERE !!! but I don't know why.
      this.TableCreated = "FUE CREADA LA DB!";
      this.DbService.setDatabase(db);
      return this.DbService.createTable();
    )
    .then(() => 
      this.TableCreated = "FUE CREADA LA TABLA!";
      return this.DbService.createFirstRunningApp();
    )
    .then(() =>
      this.TableCreated = "SE INSERTÓ LOS DATOS";
      this.splashScreen.hide();
      this.rootPage = 'HomePage';
    )
    .catch(error =>
      console.error(error);
    );
  

在 db.services.ts 中:

import  SQLiteObject  from '@ionic-native/sqlite/ngx';


export class DbService 
db: SQLiteObject = null;

  constructor()  

 setDatabase(db: SQLiteObject)
    if(this.db === null)
      this.db = db;
    
  

  createTable()
    let sql = 'CREATE TABLE IF NOT EXISTS datis(id INTEGER PRIMARY KEY AUTOINCREMENT, dati TEXT, isTrue INTEGER DEFAULT 0, dateCreated datetime default CURRENT_TIMESTAMP)';
    return this.db.executeSql(sql, []);

  

  createFirstRunningApp() //solo la primera vez se corre
    let allDate = [
      'Blablabla',
      'Something',
      'YellowBlueRed',
    ];
    let sql = 'INSERT INTO datis(dati) VALUES(?)';
    for (let dati of allDate) 
      this.db.executeSql(sql, [dati]);
    
  

this.sqlite.create( 名称:'data.db', location: 'default' // 位置字段是必需的 ).then((db: SQLiteObject)

我的信息:

Ionic:

   ionic (Ionic CLI)          : 4.1.2 (C:\Users\Tomas\AppData\Roaming\npm\node_m
odules\ionic)
   Ionic Framework            : @ionic/angular 4.0.0-beta.7
   @angular-devkit/core       : 0.7.5
   @angular-devkit/schematics : 0.7.5
   @angular/cli               : 6.1.5
   @ionic/ng-toolkit          : 1.0.8
   @ionic/schematics-angular  : 1.0.6

Cordova:

   cordova (Cordova CLI) : 8.0.0
   Cordova Platforms     : android 7.0.0
   Cordova Plugins       : cordova-plugin-ionic-keyboard 2.1.3, cordova-plugin-i
onic-webview 2.1.4, (and 4 other plugins)

System:

   NodeJS : v8.12.0 (C:\Program Files\nodejs\node.exe)
   npm    : 6.4.1
   OS     : Windows 7

有什么解决办法吗?郑重声明,我是初学者,可能代码中有什么逃逸的地方。

谢谢。

【问题讨论】:

这意味着SQLite.create 不会返回promise。不要假设每个函数都会返回 Promise,除非你已经写好了。 【参考方案1】:
ionic cordova platform add browser

然后

ionic cordova run browser

我必须运行第二个命令。使用第一个命令,因为在第一个命令之后它没有为我构建。在此之后,它起作用了。

【讨论】:

这个命令也会给出一个错误,比如:Using cordova-fetch for cordova-browser@^6.0.0 Platform browser already added。 [错误] 运行子进程cordova 时出错。科尔多瓦平台添加浏览器退出,退出代码为 1。【参考方案2】:

让我们稍微修改一下你的代码:

private createDatabase()
  const conn = this.sqlite.create(
    name: 'data.db',
    location: 'default' // the location field is required
  )
  console.log('i think the db conn is undefined', conn);
  conn.then(() => 
    // etc
  )

在这里,如果connundefined,那么您正在尝试调用undefined.then,这完全没有意义。这就是您收到错误的原因。真正的原因是它无法创建您的数据库连接。那是一个完全不同的问题。如果您按如下方式更改代码会更容易:

private createDatabase()
  const conn = this.sqlite.create(
    name: 'data.db',
    location: 'default' // the location field is required
  )
  if (conn == null) throw Error('Failed to create database connection')
  conn.then(() => 
    // etc
  )

这种及早捕获错误使代码更容易调试。

【讨论】:

现在我得到“错误:未捕获(承诺):错误:无法创建数据库连接错误:无法创建数据库连接”。看起来 sqlite.create 无法创建任何东西。有什么我想念的吗? 是的,这正是你的问题。看到错误信息告诉你现在的问题并且不再是虚假的。就像我说的,修复数据库问题是一个完全不同的问题。 不确定为什么要在 Angular 应用程序中创建数据库,数据库通常在后端创建,Angular 通过 HTTP 与它们通信。创建数据库客户端就像在每个用户机器上创建一个数据库。您可能需要后端节点服务器上的共享数据库。 如果是这样的话。然后catch 应该执行。提供的解决方案均无效。如果你达成了解决方案。然后分享【参考方案3】:

我在我的项目中使用它,它可以工作。试试看对你有没有帮助。

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

@Injectable()
export class SqliteHelperService 

  private db: SQLiteObject

  constructor(
    public platform: Platform,
    public sqlite: SQLite) 
  

  
  private createDatabase(dbName?:string): Promise<SQLiteObject> 
    return this.platform.ready()
      .then((readySource: string) => 
        return this.sqlite.create( 
          name: dbName || 'ks.db',
          location: 'default'
        ).then((db: SQLiteObject) => 
          this.db = db;
          return this.db;
        ).catch((error: Error) => 
          console.log('Error on open or create database: ', error);
          return Promise.reject(error.message || error);
        );  
      );  
  

  getDb(dbName?:string, newOpen?:boolean): Promise<SQLiteObject>
    if (newOpen) return this.createDatabase(dbName);
    return (this.db) ? Promise.resolve(this.db) : this.createDatabase(dbName);
    

【讨论】:

好的,我会试试你的代码。我会告诉你它是否有效。谢谢。【参考方案4】:

我也在使用 sqlite whit angular 6 和 ionic v4,我认为您返回 db 的所有对象的方式有些脏,您将在服务上执行 db 的所有交互并仅返回结果.

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

@Injectable()
export class SQLiteService 

  constructor(
    private sqlite: SQLite
  ) 

  rawQuery(queryText: string, params?: any[]): any 
    return new Promise((resolve, reject) => 
      this.sqlite.create(name: 'data.db', location: 'default').then((db: SQLiteObject) => 
        db.executeSql(queryText, params || []).then((data) => 
          resolve(data);
        ).catch(error => reject(error));
      ).catch(error => reject(error));
    );
  

【讨论】:

以上是关于带有 Ionic 4 的 SQLite?无法读取未定义类型错误的属性“then”:无法读取未定义的属性“then”的主要内容,如果未能解决你的问题,请参考以下文章

Ionic 3 - 使用 --prod 标志运行时,sqlite 显示“无法读取 openDatabase 的属性”的错误

在 Ionic2 v3.4 中读取 SQLite SELECT 查询的结果

带有in运算符的Ionic3原生SQLite选择查询

ionic 使用sqlite

无法读取 Ionic 中未定义错误的属性“清单”

Ionic v4 Firebase:无法读取未定义的属性“电子邮件”