0

I have a function to insert my articles and I call this function in my page, there is no error, but the next function retrievedAllArticles() is not executed.

    public saveAllArticles(article) {
    for(let data in article) {
      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[data].article_id + ',"' +
        article[data].article_titre + "\")", {})
        .then(() => {
          console.log("Inséré");
        }).catch(e =>
        console.log("Erreur :" + JSON.stringify(e))
      );
    }
  }


  public retrieveAllArticles() {

    console.log("Retrieve");
    this.allArticles = [];
    this.db.executeSql('SELECT id FROM `all_articles`', {})
      .then((data) => {

      console.log(data);

      if(data == null) {
        return;
      }

      if(data.rows) {
        if(data.rows.length > 0) {
          for(let i = 0; i < data.rows.length; i++) {
            this.allArticles.push(data.rows.item(i).article_id);
          }
        }
      }
    });

    return this.allArticles;
  }

The console.log("Retrieve"); is not displayed, but the console.log('Inséré'); is displayed.

The constructor of my page :

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

    if (this.platform.is('cordova')) {
      sqliteService.createDatabaseFile();

      this.articlesService.getAllArticles().subscribe(article => {
        this.allArticles = article;
        this.sqliteService.saveAllArticles(this.allArticles);
      });

      this.allArticles = this.sqliteService.retrieveAllArticles();
    }
  }

After suggestions :

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

    if (this.platform.is('cordova')) {
      sqliteService.createDatabaseFile();

      this.articlesService.getAllArticles().subscribe(article => {
        this.allArticles = article;
        this.sqliteService.saveAllArticles(this.allArticles);
        this.allArticles = this.sqliteService.retrieveAllArticles();
        console.log("articles");
        console.log(this.allArticles);
      });

    }
  }

enter image description here

    public saveAllArticles(article) {

    let insertions: Array<Promise<any>> = [];
    console.log("insertions", insertions);
    for (let data in article) {
      insertions.push(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[data].article_id + ',"' +
        article[data].article_titre + "\")", {}))
      Promise.all(insertions).then(() => {
        console.log("All records have been inserted");
        this.allArticles = this.retrieveAllArticles();
      }).catch(e => {
        console.log("Erreur :" + JSON.stringify(e))
      });
    }
  }

Can you help me please ?

Thank you in advance

Valentin Harrang
  • 1,081
  • 2
  • 17
  • 34
  • 1
    You should move `this.allArticles = this.sqliteService.retrieveAllArticles();` inside of the `subscribe` callback, after `saveAllArticles`. In your current code, `retrieveAllArticles` is probably executed before the callback. – ConnorsFan Dec 18 '17 at 19:54
  • Thank you ! : D, it's normal if the console.log ("Retrieve"); is displayed before "Inserted" in my console while the insertion is done before the retrieval of articles? – Valentin Harrang Dec 18 '17 at 19:58
  • If these commands are asynchronous (as they probably are), putting `retrieveAllArticles` at the end of the callback ensures that it is executed after `saveAllArticles`. – ConnorsFan Dec 18 '17 at 20:01
  • So, it's normal ? Because when I console.log(this.allArticles); in the constructor of my page, the variable is empty – Valentin Harrang Dec 18 '17 at 20:05
  • I am not sure what the order of execution would be. Event with my first suggestion, the order is not well determined, actually. To be really sure, you should retrieve the data after `saveAllArticles` completes. – ConnorsFan Dec 18 '17 at 20:16
  • This is what I did ? (I edited) – Valentin Harrang Dec 18 '17 at 20:20
  • Sorry for the confusion. My first suggestion was not accurate. As your code is now, you call `retrieve` after calling `save`, but not after `save` has completed. Since these calls are asynchronous, `save` completes when the all the promises have been completed (when the last item has been inserted and the promise returns with `then` or `catch`). – ConnorsFan Dec 18 '17 at 20:28
  • So you could run `retrieveAllArticles` just after `console.log("Inséré")`, but only for the last inserted element. Maybe someone else can suggest an elegant way to do that... – ConnorsFan Dec 18 '17 at 20:30
  • I need all the records, not just the last one :/ – Valentin Harrang Dec 18 '17 at 21:01
  • Yes. :-) But `retrieve` should be executed only after the last one has been inserted. You can try the (untested) code in my answer. – ConnorsFan Dec 18 '17 at 21:03

1 Answers1

0

To make sure that you retrieve the data after all the saving operations have completed, you can try this:

public saveAllArticles(article) {
  // Make an array of all promises
  let insertions: Array<Promise<any>> = [];
  for (let data of article) {
    insertions.push(this.db.executeSql("INSERT INTO ...", {}));
  }
  // Execute all promises and retrieve all articles afterwards
  Promise.all(insertions).then(() => {
      console.log("All records have been inserted");
      this.allArticles = this.sqliteService.retrieveAllArticles();
    }).catch(e => {
      console.log("Error: " + JSON.stringify(e))
    });
}

The method for grouping of promises is taken from this answer by Günter Zöchbauer.

ConnorsFan
  • 70,558
  • 13
  • 122
  • 146