【问题标题】:Uncaught (in promise): TypeError: Cannot read property 'executeSql' of undefined未捕获(承诺):TypeError:无法读取未定义的属性“executeSql”
【发布时间】:2018-05-28 13:16:41
【问题描述】:

我从我的 JSON API 异步获取我的文章,我想在用户没有互联网连接时使用 SQLite 进行本地存储,但我有 这两个错误:

cordova_not_available

错误错误:未捕获(承诺中):TypeError:无法读取未定义的属性“executeSql” TypeError:无法读取未定义的属性“executeSql” 在 SqliteService.webpackJsonp.173.SqliteService.createTables (Sqlite.service.ts:30) 在 SqliteService.webpackJsonp.173.SqliteService.saveAllArticles (Sqlite.service.ts:114) 在新的 AlaUnePage

我创建了一个服务 sqlite.service.ts,它应该在我调用 AlaUnePage 的构造函数时创建我的数据库、我的表并插入每篇文章。

我的服务代码:

    import {Injectable} from '@angular/core';
import {SQLite, SQLiteObject} from '@ionic-native/sqlite';
import {ArticlesService} from "./articles.service";

const DATABASE_FILE_NAME: string = "data.db";

@Injectable()
export class SqliteService {

  private db: SQLiteObject;

  constructor(protected sqlite: SQLite, protected articlesService: ArticlesService) {
  }

  public createDatabaseFile() {
    this.sqlite.create({
      name: DATABASE_FILE_NAME,
      location: 'default'
    })
      .then((db: SQLiteObject) => {
        this.db = db;
        this.createTables();
        console.log("Database créée");
      })
      .catch(e => console.log("Erreur : "+e));
  }

  public createTables() {
    console.log('ici');
    this.db.executeSql(
      'CREATE TABLE IF NOT EXISTS all_articles(' +
      'id INT PRIMARY KEY, ' +
      'titre TEXT, ' +
      'introduction TEXT, ' +
      'image TEXT, ' +
      'redacteur_nom TEXT, ' +
      'redacteur_twitter TEXT, ' +
      'date_publication NUMERIC, ' +
      'contenu_part1 TEXT, ' +
      'tweet TEXT,' +
      'image2 TEXT, ' +
      'contenu_part2 TEXT, ' +
      'tweet2 TEXT, ' +
      'image3 TEXT, ' +
      'contenu_part3 TEXT, ' +
      'tweet3 TEXT, ' +
      'image4 TEXT, ' +
      'contenu_part4 TEXT, ' +
      'tweet4 TEXT, ' +
      'image5 TEXT, ' +
      'contenu_part5 TEXT, ' +
      'tweet5 TEXT, ' +
      'image6 TEXT, ' +
      'contenu_part6 TEXT, ' +
      'tweet6 TEXT, ' +
      'image7 TEXT, ' +
      'contenu_part7 TEXT, ' +
      'tweet7 TEXT, ' +
      'image8 TEXT, ' +
      'contenu_part8 TEXT, ' +
      'tweet8 TEXT, ' +
      'image9 TEXT, ' +
      'contenu_part9 TEXT, ' +
      'tweet9 TEXT, ' +
      'image10 TEXT, ' +
      'contenu_part10 TEXT, ' +
      'tweet10 TEXT)', {})
      .then(() => {
        this.db.executeSql(
          'CREATE TABLE IF NOT EXISTS all_articles(' +
          'id INT PRIMARY KEY, ' +
          'titre TEXT, ' +
          'introduction TEXT, ' +
          'image TEXT, ' +
          'redacteur_nom TEXT, ' +
          'redacteur_twitter TEXT, ' +
          'date_publication NUMERIC, ' +
          'contenu_part1 TEXT, ' +
          'tweet TEXT,' +
          'image2 TEXT, ' +
          'contenu_part2 TEXT, ' +
          'tweet2 TEXT, ' +
          'image3 TEXT, ' +
          'contenu_part3 TEXT, ' +
          'tweet3 TEXT, ' +
          'image4 TEXT, ' +
          'contenu_part4 TEXT, ' +
          'tweet4 TEXT, ' +
          'image5 TEXT, ' +
          'contenu_part5 TEXT, ' +
          'tweet5 TEXT, ' +
          'image6 TEXT, ' +
          'contenu_part6 TEXT, ' +
          'tweet6 TEXT, ' +
          'image7 TEXT, ' +
          'contenu_part7 TEXT, ' +
          'tweet7 TEXT, ' +
          'image8 TEXT, ' +
          'contenu_part8 TEXT, ' +
          'tweet8 TEXT, ' +
          'image9 TEXT, ' +
          'contenu_part9 TEXT, ' +
          'tweet9 TEXT, ' +
          'image10 TEXT, ' +
          'contenu_part10 TEXT, ' +
          'tweet10 TEXT)', {})
          .then(() => console.log('Executed SQL'))
          .catch(e => console.log(e));
      }).catch(e => console.log(e));
  }

  public saveAllArticles(allArticles)
  {
    this.createTables();
    allArticles.subscribe(article => {
      console.log(article['article_id']);
      this.db.executeSql('INSERT INTO all_articles (' +
        'id,' +
        'titre,' +
        'introduction,' +
        'image,' +
        'redacteur_nom,' +
        'redacteur_twitter,' +
        'date_publication,' +
        'contenu_part1,' +
        'tweet,' +
        'image2,' +
        'contenu_part2,' +
        'tweet2,' +
        'image3,' +
        'contenu_part3,' +
        'tweet3,' +
        'image4,' +
        'contenu_part4,' +
        'tweet4,' +
        'image5,' +
        'contenu_part5,' +
        'tweet5,' +
        'image6,' +
        'contenu_part6,' +
        'tweet6,' +
        'image7,' +
        'contenu_part7,' +
        'tweet7,' +
        'image8,' +
        'contenu_part8,' +
        'tweet8,' +
        'image9,' +
        'contenu_part9,' +
        'tweet9,' +
        'image10,' +
        'contenu_part10,' +
        'tweet10) VALUES ('
        +article.article_id+ ','
        +article.article_titre+ ',' +
        +article.article_introduction+ ',' +
        +article.article_image+ ',' +
        +article.article_redacteur_nom+ ',' +
        +article.article_redacteur_twitter+ ',' +
        +article.article_date_publication+ ',' +
        +article.article_contenu_part1+ ',' +
        +article.article_tweet+ ',' +
        +article.article_image2+ ',' +
        +article.article_contenu_part2+ ',' +
        +article.article_tweet2+ ',' +
        +article.article_image3+ ',' +
        +article.article_contenu_part3+ ',' +
        +article.article_tweet3+ ',' +
        +article.article_image4+ ',' +
        +article.article_contenu_part4+ ',' +
        +article.article_tweet4+ ',' +
        +article.article_image5+ ',' +
        +article.article_contenu_part5+ ',' +
        +article.article_tweet5+ ',' +
        +article.article_image6+ ',' +
        +article.article_contenu_part6+ ',' +
        +article.article_tweet6+ ',' +
        +article.article_image7+ ',' +
        +article.article_contenu_part7+ ',' +
        +article.article_tweet7+ ',' +
        +article.article_image8+ ',' +
        +article.article_contenu_part8+ ',' +
        +article.article_tweet8+ ',' +
        +article.article_image9+ ',' +
        +article.article_contenu_part9+ ',' +
        +article.article_tweet9+ ',' +
        +article.article_image10+ ',' +
        +article.article_contenu_part10+ ',' +
        +article.article_tweet10+
        ')', {})
        .then(() => {
          this.db.executeSql('', {})
            .then(() => console.log('Executed SQL'))
            .catch(e => console.log(e));
        }).catch(e => console.log(e));
    });
  }
}

我页面中的构造函数:

      constructor(public navCtrl: NavController,
              public modalCtrl: ModalController,
              protected articlesService: ArticlesService,
              protected sqliteService: SqliteService,
              private network: Network,
              public toastCtrl: ToastController)
  {
    this.observable$ = this.articlesService.getAllArticles();
    sqliteService.createDatabaseFile();
    this.sqliteService.saveAllArticles(this.observable$);
  }

根据您的建议:

你能帮帮我吗?

提前致谢

【问题讨论】:

    标签: angular sqlite typescript ionic-framework local-storage


    【解决方案1】:

    此代码中存在异步问题:

    sqliteService.createDatabaseFile();
    this.sqliteService.saveAllArticles(this.observable$);
    

    saveAllArticles 可能在createDatabaseFile 之前被调用,所以为什么你会得到undefined db

    解决方案是在服务中的方法中返回一个promise(因为sqlite已经使用promise),例如:

    public createDatabaseFile(): Promise<SQLiteObject> {
        let promise = this.sqlite.create({
          name: DATABASE_FILE_NAME,
          location: 'default'
        });
        promise.then((db: SQLiteObject) => {
            this.db = db;
            this.createTables();
            console.log("Database créée");
        }).catch(e => console.log("Erreur : "+e));
    
        return promise;
    }
    
    public createTables(): Promise<void> {
        return this.db.executeSql(
          'CREATE TABLE IF NOT EXISTS all_articles...'
        ).then(()=> {
          return this.db.executeSql('CREATE TABLE IF NOT EXISTS all_articles ...')
        });
    }
    

    现在他们都返回了一个承诺,你可以像这样使用:

    this.observable$ = this.articlesService.getAllArticles();
    sqliteService.createDatabaseFile().then( (db) => {
        this.sqliteService.createTables().then( () => {
           this.sqliteService.saveAllArticles(this.observable$);
        })
     });
    

    如果您也想更改 saveAllArticles 以使用 Promise:

    public saveAllArticles(allArticles)
    {
        // you need to import toPromise() 
        // import 'rxjs/add/operator/toPromise';
        return allArticles.toPromise().then(article => {
          return this.db.executeSql('INSERT INTO all_articles (...)')
        }).then(()=> {
          return this.db.executeSql('', {})
        })
    }
    

    【讨论】:

    • 我应该使用 Promise 而不是 Promise 吗?因为“回报承诺”;在 createDatabaseFile() 方法中是红色下划线
    • @ElGecko_76 哦,是的,那么您也可以使用返回的数据库,更新答案。我知道你会解决这个问题,我只是把正确的方法做到这一点:)
    • 我必须改用这段代码吗? this.observable$ = this.articlesService.getAllArticles(); sqliteService.createDatabaseFile().then( db => this.sqliteService.createTables().then(((value)=> this.sqliteService.saveAllArticles(this.observable$)) ));
    • 谢谢 :) 我还有最后一个问题,要从我的本地存储中检索数据,我必须在我的服务中创建一个函数并按照你给我的代码在我的构造函数中调用它?
    • 数据返回 null :s
    猜你喜欢
    • 2019-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-03
    • 2020-09-24
    • 1970-01-01
    • 2020-03-24
    • 2021-05-14
    相关资源
    最近更新 更多